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
*);
68 insert_link_name(struct name
*);
70 insert_link_namelist(struct name
*);
72 insert_ss_name(struct name
*);
74 insert_ss_namelist(struct name
*);
76 insert_mlink(struct name
*, int);
78 insert_vlink(struct name
*, int);
80 insert_ref(struct odat
*, int);
86 insert_map(struct name
*, int, int, int, int, uint8_t*);
88 insert_framesheet(struct name
*, int, int, int, int, uint8_t*);
92 //type safety handled by macro expansion (do not call these directly from code, make dependent macros for access to these)
93 #define CHUNKS_LEN(STACK) ((STACK).csp - (STACK).chunks)
94 #define CURRENT_CHUNK(STACK) ((STACK).chunks[CHUNKS_LEN(STACK) - 1])
95 #define CHUNKS_FULL(STACK) ( (STACK).csp >= \
96 (STACK).chunks + MAX_CHUNKS * (STACK).chunk_size)
97 #define CURRENT_DSP(STACK,TYPE) ((TYPE*) ((STACK).dsp[CHUNKS_LEN(STACK) - 1]))
98 #define DATA_FULL(STACK,TYPE) ((void*) CURRENT_DSP(STACK,TYPE) >= \
99 (CURRENT_CHUNK(STACK) + (STACK).chunk_size))
100 #define CSP_PUSH(STACK) (*(++(STACK).csp) = malloc((STACK).chunk_size))
101 #define CURRENT_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 1])
102 #define PREVIOUS_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 2])
103 #define ALLOC_DAT(STACK,TYPE) (++CURRENT_DATP(STACK,TYPE))
104 #define INIT_STACK(STACK,TYPE) \
106 (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \
107 (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \
109 for( i = 0; i < MAX_CHUNKS; i++){ \
110 (STACK).dsp[i] += pagesize; \
113 //Stack-specific macros (called directly from code (safety enforcement)
114 #define INIT_ODAT() (INIT_STACK(ocs, struct odat))
115 #define CURRENT_ODAT() (CURRENT_DATP(ocs,struct odat))
116 #define ODAT_FULL() (DATA_FULL(ocs,struct odat))
117 #define ODAT_ALLOC() (ALLOC_DAT(ocs,struct odat))
118 #define OCS_FULL() (CHUNKS_FULL(ocs))
119 #define INIT_VDAT() (INIT_STACK(vcs, struct vdat))
120 #define CURRENT_VDAT() (CURRENT_DATP(vcs,struct vdat))
121 #define VDAT_FULL() (DATA_FULL(vcs,struct vdat))
122 #define VDAT_ALLOC() (ALLOC_DAT(vcs,struct vdat))
123 #define VCS_FULL() (CHUNKS_FULL(vcs))
124 #define INIT_CDAT() (INIT_STACK(ccs, struct cdat))
125 #define CURRENT_CDAT() (CURRENT_DATP(ccs,struct cdat))
126 #define CDAT_FULL() (DATA_FULL(ccs, struct cdat))
127 #define CDAT_ALLOC() (ALLOC_DAT(ccs, struct cdat))
128 #define CCS_FULL() (CHUNKS_FULL(ccs))
129 #define INIT_SET() (INIT_STACK(scs, struct set))
130 #define CURRENT_SET() (CURRENT_DATP(scs, struct set))
131 #define SET_FULL() (DATA_FULL(scs, struct set))
132 #define SET_ALLOC() (ALLOC_DAT(scs, struct set))
133 #define SCS_FULL() (CHUNKS_FULL(scs))
134 #define INIT_LINK() (INIT_STACK(lcs, struct link))
135 #define CURRENT_LINK() (CURRENT_DATP(lcs,struct link))
136 #define LDAT_FULL() (DATA_FULL(lcs, struct link))
137 #define LDAT_ALLOC() (ALLOC_DAT(lcs, struct link))
138 #define LCS_FULL() (CHUNKS_FULL(lcs))
139 #define INIT_POST() (INIT_STACK(rcs, struct ref))
140 #define CURRENT_POST() (CURRENT_DATP(pcs,struct ref))
141 #define POST_FULL() (DATA_FULL(pcs,struct ref))
142 #define POST_ALLOC() (ALLOC_DAT(pcs,struct ref))
143 #define PCS_FULL() (CHUNKS_FULL(pcs))
144 #define INIT_REF() (INIT_STACK(rcs, struct ref))
145 #define CURRENT_REF() (CURRENT_DATP(rcs,struct ref))
146 #define PREVIOUS_REF() (PREVIOUS_DATP(rcs, struct ref))
147 #define REF_FULL() (DATA_FULL(rcs,struct ref))
148 #define REF_ALLOC() (ALLOC_DAT(rcs,struct ref))
149 #define RCS_FULL() (CHUNKS_FULL(rcs))
151 #define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models])
155 /* Dynamically allocate memory for a class data structure,
156 or cdat, after a class has been identified in a grammar.
157 We also create a stack of class pointers so that
158 we can access the cdat during processing of that
159 cdats sets and elements, a requirement because the
160 nature of recursive classes prevents us from accessing
161 the cdat based on the previous index into cdat_buf,
162 which is a list of all allocated cdats
163 /* Cdats: A cdat is a class data structure. Cdats serve as the central */
164 /* data types of the IR. Cdats contain pointers to their subclasses so that the relationship between */
165 /* classes can be determined, but the subclasses are not represented inside */
166 /* of the cdat itself but rather in subsequent cdats in cdat_buf. We */
167 /* can determine the number of subclasses (the last index into cdat_buf */
168 /* that represents a subclass of some arbitrary cdat) each cdat has by */
169 /* incrementing num_classes during parse time. */
170 /* TODO: Should classes point to their parent class? */
171 /* TODO: Talk more about cdat set structure */
177 struct cdat
* class_list
[MAX_CLASSES
];
178 struct set
* set_list
[MAX_SETS
];
182 /* Sets: What is a set?
187 The set is populated at parse time AFTER the elements are populated, due to
188 the nature of bottom up parsing. */
192 struct set
* set_list
[MAX_SETS
];
195 /* Refs: Each set/ele has a reference to its object data (odat) through a refid.
196 refids are unsigned 64 byte integers that map to the hex values RGBA. During
197 the construction of the directory structure, users can choose a RGBA value for
198 each object that any other object can refer to via links (see link). If a user
199 does not choose an RGBA value, then the object is given one from the system space.
200 We maintain a doubly linked list of refs in the ref_buf at parse time so that
201 links can be resolved after the parsing of the directory structure is complete.
202 For every 16th ref, we create a post so that we can reduce on the search time for
206 int type
; //TODO: Is this needed?
210 int refid
; //0xFFFFFF->digit
213 /* Links: At parse time, a set/ele can include a link in their
214 grammar representation instead of the actual data and this signifies
215 to the APC that that set/ele wishes to use the data of another
216 set/ele, either its video data (vdat) or object data (odat). The link
217 itself contains the type of link it is, the refid OR name, and
218 which set/ele created the link. During parse time, links can be made
219 to o/vdats that have yet to be parsed. In order to accomodate for this,
220 we resolve all links AFTER parse time by iterating through the link_buf,
221 finding the refid that was stored for some object (if the refid exists),
222 and creating a relative pointer from the original object to the data that
225 /* TODO: Explain links more betta */
233 struct name src_animname
;
234 struct name src_namelist
[MAX_DEPTH
];
239 struct name src_mapname
;
240 struct name src_namelist
[MAX_DEPTH
];
251 /* From: src odat ()To: dest odat (refid)*/
253 int type
; //1 = olink, 2 = vlink, 3 = mlink
255 int dest_refid
; //if it exists
256 struct odat
* dest_odatp
;
264 uint8_t filepath
[FPATH_MAX
];
267 /* Odats: Odats consist of the object data necessary for
268 each object. Odats are sometimes referred to as archetypes
269 at compile-time, in order to distinguish the difference from
270 a runtime object and a compile-time object.
271 TODO: Need more info about objects at runtime, to described
272 the reasoning behind odat structure at compile-time*/
280 struct odat
* parent_odatp
; // odat == set ? null : set refid
281 struct ref
* refp
; /* pointer to it's ref on ref_list */
282 struct map map
; //only valid if odat ismap
286 /* A framesheet is a grouping of animation frames in
287 a single direction (N,W,S,E) */
295 /* A model is a collection of framesheets for every
296 direction (N,W,S,E,NW,NE,SW,SE)*/
297 /* NAMED spritesheet */
300 uint8_t filepath
[PATH_MAX
];
301 struct framesheet spritesheet
[8]; //one for each
304 /* Vdat: Vdats are the video data of each object. They can not be
305 created as a stand alone object (because they consist solely
306 of animation information and not the map which the
307 animation manipulates). Vdats have a list of models for every
308 animation that the vdats odat can do for that vdat*/
310 struct odat
* creator
; //pointer to odat that made this vdat
312 uint8_t filename
[FNAME_MAX
];
315 uint8_t filepath
[FPATH_MAX
];
316 struct model model_list
[MAX_MODELS
];
321 { struct name namelist
[MAX_DEPTH
];
330 { struct set_frame set_frames
[MAX_DEPTH
];
331 int curr_depth
; //used to get most recently created set/odat + to check for undefined parents of namelists
335 //"type free" chunk stacking
337 { void* chunks
[MAX_CHUNKS
];
338 void* *csp
; //chunk stack pointer
339 void* dsp
[MAX_CHUNKS
]; //dat stack pointer (per chunk)
340 int chunk_size
; //size of a chunk (including its forfeited page)
341 int max_dats
; //number of dats per chunk for this stack
342 } ocs
, vcs
, ccs
, rcs
, lcs
, pcs
, scs
; //odat, vdat, cdat, ref, link, post stacks
347 /* The cdat_stack is a stack pointers to cdat pointers, the top of which is
348 the cdat that is currently being parsed. Whenever a new cdat is recognized
349 by the grammar (CLOPEN), a cdat is pushed onto the cdat_stack, and we refer
350 to this cdat through the macro CURR_CDAT. By keeping a cdat_stack, we have
351 access to the current cdat so that the elements and sets can populate themselves
352 in the cdat accordingly. */
355 struct cdat
* cdat_stack
[MAX_CLASSES
];
356 struct cdat
** cdat_stackp
;
359 struct name set_namelist
[MAX_DEPTH
];
360 int set_numnames
= 0;
362 struct name link_namelist
[MAX_DEPTH
];
363 int link_numnames
= 0;
370 int ss_refid
= 0x0FFFFFFF; /* system space for refids */
377 /* The initalization function of the IR. */
383 uint8_t root
[4] = "root";
385 u8_stpncpy(name
.name
, root
, 4);
387 pagesize
= sysconf(_SC_PAGESIZE
);
388 printf("pagesize is %l\n", pagesize
);
391 *cdat_stackp
= CURRENT_CDAT();
392 name_u8_cpy(&(*cdat_stackp
)->name
, &name
);
396 VDAT_ALLOC(); //NULL vdat
397 VDAT_ALLOC(); //First vdat req. because alloc_vdat happens after vdat is reduced
413 for(i
= 0; i
< CHUNKS_LEN(ccs
) ; i
++)
417 for(i
= 0; i
< CHUNKS_LEN(ocs
); i
++)
421 for(i
= 0; i
< CHUNKS_LEN(vcs
) ; i
++)
425 for(i
= 0; i
< CHUNKS_LEN(rcs
); i
++)
429 for(i
= 0; i
< CHUNKS_LEN(lcs
); i
++)
433 for(i
= 0; i
< CHUNKS_LEN(pcs
); i
++)
446 { fprintf(stderr
, "You have allocated to many (%d) cdats ", num_cdats
);
455 return CURRENT_CDAT();
458 //these should probably be inline
466 { fprintf(stderr
, "You have allocated to many (%d) odats ", num_odats
);
475 return CURRENT_ODAT();
484 { fprintf(stderr
, "You have allocated to many (%d) vdats ", num_vdats
);
502 { fprintf(stderr
, "You have allocated to many (%d) sets ", num_sets
);
511 return CURRENT_SET();
521 { fprintf(stderr
, "You have allocated to many (%d) links ", num_links
);
530 return CURRENT_LINK();
540 { fprintf(stderr
, "You have allocated to many (%d) refs ", num_refs
);
550 if(num_refs
% 16 == 0)
551 { CURRENT_POST() = CURRENT_REF();
555 return CURRENT_REF();
563 { fprintf(stderr
, "You have allocated to many (%d) refs ", num_posts
);
578 return (*cdat_stackp
);
585 return CURRENT_ODAT();
592 return CURRENT_VDAT();
599 return CURRENT_SET();
608 for(i
= 0; i
<= depth
; i
++)
609 { if(!(setp
= setp
->set_list
[setp
->num_sets
]))
610 { printf("You are trying to access a set that does not exist irmem.c\n");
623 return CURRENT_REF();
629 return PREVIOUS_REF();
635 return &CURRENT_MODEL();
644 struct cdat
* curr_cdatp
;
646 curr_cdatp
= alloc_cdat();
648 name_u8_cpy(&curr_cdatp
->name
, name
);
649 curr_cdatp
->idx
= num_cdats
;
651 /* Set the cdat as a subclass of the previous cdat */
652 (*cdat_stackp
)->class_list
[(*cdat_stackp
)->num_classes
] = curr_cdatp
;
653 /* Push the cdat onto the cdat_stack */
654 *++cdat_stackp
= curr_cdatp
;
671 //Push name onto current namelist, set the set_namelist.
672 name_u8_cpy(&set_namelist
[set_numnames
++], name
);
682 { int depth
, nameidx
, i
;
684 insert_set_name(name
);
686 //Check if entire string matches first? Only possible if namelist is contiguous (uint8_t strings seperated by \0)
687 //Create odats/sets for each name in namelist where nameidx > ns_depth
688 //first check if any parts of namelist matches what is currently on namestack
689 //we can gauruntee that from ns_depth + 1 -> set_numnames namelists dont match. x
692 //if name_list doesnt match, from the first depth at which namelist doesnt match
693 //remove the nameframes namelist (zero out ones below?) and replace with current namelist,
694 //then allocate a new odat and set it to the current set_frame.
695 for( depth
= 0; depth
< set_numnames
; depth
++ )
696 { for (nameidx
= 0; nameidx
<= depth
; nameidx
++)
697 { if( name_u8_cmp(&set_namelist
[nameidx
], &ss
.set_frames
[depth
].namelist
[nameidx
]) != 0 )
698 { /* Populate the namelist of the set at the current depth */
699 for(i
= 0; i
<= depth
; i
++)
700 name_u8_cpy(&ss
.set_frames
[depth
].namelist
[i
], &set_namelist
[i
]);
702 /* Alloc set and odat */
703 ss
.set_frames
[depth
].odatp
= alloc_odat();
704 ss
.set_frames
[depth
].setp
= alloc_set();
706 /* populate set/odat name and cdat_idx */
707 name_u8_cpy(&ss
.set_frames
[depth
].odatp
->name
, &set_namelist
[depth
]);
708 ss
.set_frames
[depth
].setp
->cdat_idx
= ( *cdat_stackp
)->idx
;
710 /* Insert allocated set and odat into their respective trees if there is a depth
711 (they have parents) */
713 { ss
.set_frames
[depth
].odatp
->parent_odatp
= ss
.set_frames
[depth
-1].odatp
;
714 if(ss
.set_frames
[depth
-1].setp
->num_sets
< MAX_SETS
)
715 ss
.set_frames
[depth
-1].setp
->set_list
[ss
.set_frames
[depth
-1].setp
->num_sets
++] = ss
.set_frames
[depth
].setp
;
717 { printf("you have allocated too many sets in insert_namelist()\n");
721 else /* no parent set, so assign to cdat set_list */
722 { ss
.set_frames
[depth
].odatp
->parent_odatp
= NULL
; //no parent odat = NULL.
723 if(curr_cdat_set()->num_sets
< MAX_SETS
)
724 curr_cdat_set()->set_list
[curr_cdat_set()->num_sets
++] = ss
.set_frames
[depth
].setp
;
726 { printf("you have allocated too many sets in insert_namelist()\n");
732 ss
.set_frames
[depth
].num_names
= set_numnames
;
733 ss
.curr_depth
= depth
;
743 /*. We create new odats for each map variant that are children of the current odat/set
744 , set their name as the map name, and identify them by marking them as a map. This lets
745 us distinguish between sibling odatsthat have the same name because the map of the parent
746 odat had the same name as another, regular odat*/
747 #define CURR_SS_FRAME() (ss.set_frames[ss.curr_depth])
748 #define CURR_SS_SETP() (CURR_SS_FRAME().setp)
749 #define CURR_SS_ODATP() (CURR_SS_FRAME().odatp)
752 ( name
, direction
, height
, width
, refid
, filepath
)
754 int direction
, height
, width
, refid
;
757 struct odat
* curr_mem_odatp
; //pointer to odat in odat_buf
758 struct set
* curr_mem_setp
; //pointer to set in set_buf
761 curr_mem_odatp
= alloc_odat();
762 curr_mem_setp
= alloc_set();
763 //Create a new odat, make its parent be the set. Make a set for mdat, its name should
764 //be the name of the odat + name of model. That makes a conflict beween odats that are named
765 //the same thing as the model of a sibling odat that was created from a map. They can have
766 //same name if the map odat is marked. So mark the map odat.
769 curr_mem_odatp
->parent_odatp
= CURR_SS_ODATP();
770 //insert into set_list
771 if(CURR_SS_SETP()->num_sets
< MAX_SETS
)
772 CURR_SS_SETP()->set_list
[CURR_SS_SETP()->num_sets
++] = curr_mem_setp
;
774 { printf("You have allocated to many sets, error in insert_map()\n");
778 //indicate that newly created odat is a map
779 curr_mem_odatp
->ismap
= 1;
780 //set odat and set name
781 name_u8_cpy(&curr_mem_odatp
->name
, name
);
783 /* set cdat idx values for both set and odat */
784 curr_mem_setp
->cdat_idx
= num_cdats
;
787 /* Generate refid if needed, put into ref_buf */
791 insert_ref(curr_mem_odatp
, refid
);
793 /* If current odatp on stack has a link, then we need to make our own link. just set the vdat_idx */
794 if(CURR_SS_ODATP()->vdat_idx
= 0)
796 linkp
= alloc_link();
797 linkp
->type
= CURR_SS_ODATP()->linkp
->type
;
798 linkp
->dest_odatp
= CURR_SS_ODATP();
799 linkp
->dest_refid
= refid
;
800 linkp
->link_t
.mlink
.src_refid
= CURR_SS_ODATP()->linkp
->link_t
.mlink
.src_refid
;
802 /* Copy the animation name of the vlink*/
803 name_u8_cpy(&linkp
->link_t
.vlink
.src_animname
, &CURR_SS_ODATP()->linkp
->link_t
.vlink
.src_animname
);
804 /* Copy the namelist of the vlink*/
805 for(i
= 0; i
< MAX_DEPTH
; i
++)
806 name_u8_cpy(&linkp
->link_t
.vlink
.src_namelist
[i
], &CURR_SS_ODATP()->linkp
->link_t
.vlink
.src_namelist
[i
]);
809 curr_mem_odatp
->vdat_idx
= CURR_SS_ODATP()->vdat_idx
;
817 /* 11/22 Each vdat has a multiple models. Each model has 8 framesheets, one in each
818 direction, that create a spritesheet. Inserting framesheets into the correct
819 model is just a matter of checking whether or not the last models name matches
821 the current one. We can never get a framesheet that is for the same model before
822 AND after some other model, due to alphasorting of the files in each directory */
825 ( model_name
, direction
, height
, width
, refid
, filepath
)
826 struct name
* model_name
;
827 int direction
, height
, width
, refid
;
829 { struct vdat
* curr_vdatp
;
830 struct model
* curr_modelp
;
831 static struct name last_model_name
[32];
834 curr_vdatp
= curr_vdat();
836 /* If the model name changed, that means there are no more
837 framesheets for that model to be processed, a guaruntee we make
838 b/c the filenames are alphabetically sorted */
839 if(!name_u8_cmp(last_model_name
, model_name
))
840 { if(curr_vdatp
->num_models
)
841 curr_vdatp
->num_models
++;
842 num_models
++; // total number of models
846 if(CURR_SS_ODATP()->refid
== 0)
849 insert_ref(CURR_SS_ODATP(), refid
);//given a odatp and a refid, insert the odatp into the ref_buf.
850 //push ref into ref_buf.
853 printf("error: redefining a previously set refid\n");
855 curr_modelp
= curr_model();
857 name_u8_cpy(&curr_modelp
->name
, model_name
);
858 curr_modelp
->spritesheet
[direction
].height
= height
;
859 curr_modelp
->spritesheet
[direction
].width
= width
;
861 name_u8_cpy(last_model_name
, model_name
);
868 //src_path is stored in link_namelist
871 ( src_mapname
, src_refid
)
872 struct name
* src_mapname
;
874 { struct link
* linkp
;
877 linkp
= alloc_link();
881 /* set the name of the src map for the link, if a name exists */
883 name_u8_cpy(&linkp
->link_t
.mlink
.src_mapname
, src_mapname
);
884 /* Set the source ref id of the link */
885 linkp
->link_t
.mlink
.src_refid
= src_refid
;
886 /* Copy the entire namelist of the link, if it exists */
887 for(i
= 0; i
< link_numnames
; i
--) //TODO MAX_DEPTH -> link_namelist_num??
888 { name_u8_cpy(&linkp
->link_t
.mlink
.src_namelist
[i
], &link_namelist
[i
]);
889 name_u8_set(&link_namelist
[i
], (ucs4_t
) 0);
893 linkp
->dest_odatp
= CURR_SS_ODATP();//current odat on set_stack
902 //Push name onto current namelist, set the set_namelist.
903 name_u8_cpy(&link_namelist
[link_numnames
++], name
);
907 /* Nearly identical to mlink */
910 ( src_animname
, src_refid
)
911 struct name
* src_animname
;
913 { struct link
* linkp
;
916 linkp
= alloc_link();
921 /* set the name of the src animname for the link, if a name exists */
923 name_u8_cpy(&linkp
->link_t
.vlink
.src_animname
, src_animname
);
925 /* Set the source ref id of the link */
926 linkp
->link_t
.mlink
.src_refid
= src_refid
;
928 /* Copy the entire namelist of the link, if it exists */
929 for(i
= 0; i
< link_numnames
; i
++) //TODO MAX_DEPTH -> link_namelist_num??
930 { name_u8_cpy(&linkp
->link_t
.vlink
.src_namelist
[i
], &link_namelist
[i
]);
931 name_u8_set(&link_namelist
[i
], (ucs4_t
) 0);//set to null for next link_namelist
934 linkp
->dest_odatp
= CURR_SS_ODATP();//current odat on set_stack
939 /* TODO: Do we really need to store the prev/next pointer? iterating through the
940 ref_buf could be achieved by iterating until the num_refs anyway. */
946 { struct ref
* curr_refp
;
947 struct ref
* prev_refp
;
949 curr_refp
= alloc_ref();
950 prev_refp
= prev_ref();
952 prev_refp
->nextref
= curr_refp
;
953 curr_refp
->lastref
= prev_refp
;
955 curr_refp
->odatp
= odatp
;
956 curr_refp
->refid
= refid
;
960 CURRENT_POST()->refid
= refid
;
961 CURRENT_POST()->odatp
= odatp
;
971 { struct odat
* curr_ss_odatp
;
972 struct vdat
* curr_vdatp
;
974 curr_vdatp
->creator
= curr_ss_odatp
;
975 curr_ss_odatp
->vdat_idx
= num_vdats
;
976 curr_ss_odatp
->vdatp
= curr_vdatp
;
981 insert_refid_statement
984 { CURR_SS_ODATP()->refid
= refid
;
989 /* Called in the reduction of a set. While both odats (eles and sets)
990 have identical label terminals, we are unable to give a single grammatical rule
991 for both due to how we allocate odats in the odat buf. Due to the
992 nature of bottom up parsing, the set label is recognized first, and then the
993 sets elements are recognized. This means that after we have processed the sets elemenets,
994 the curr_odat is going to be the last element and NOT the set that was first allocated.
995 To get around this, we create a global variable set_odatp that will store the pointer
996 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
997 have access to it. Curr set points the sets representation in the cdat, curr_set_odatp
998 points to the sets representation as an odat*/
1000 //TODO: Add insert_set_ref()
1001 //TODO: Is this the correct allocation scheme? No do the one ken suggested
1008 struct set
* curr_setp
;
1010 curr_setp
= curr_set();
1011 curr_set_odatp
= alloc_odat();
1013 u8_cpy(curr_set_odatp
->name
, name
, 32);
1014 u8_cpy(curr_setp
->name
, name
, 32);
1015 curr_set_odatp
->parent_odatp
= NULL
;
1020 /* Inserting a olink instead of a set. Set is really just a placeholder
1021 for another set. Allocate the memory for the set so taht it can be populated*/
1027 struct set
* curr_setp
;
1029 curr_setp
= curr_set();
1031 curr_setp
->refid
= refid
;
1041 struct cdat
* curr_cdatp
;
1042 struct odat
* curr_odatp
;
1043 struct link
* curr_linkp
;
1046 curr_cdatp
= curr_cdat();
1047 curr_odatp
= curr_odat();
1048 curr_linkp
= alloc_link();
1050 /* Insert vlink into link_stack so that it gets processed at
1052 curr_linkp
->type
= 2;
1053 /* Store the target odat information*/
1054 curr_linkp
->link_t
.vlink
.refid
= refid
;
1055 u8_cpy(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
1056 /* Store the linking odat/cdat information */
1057 curr_linkp
->classp
= curr_cdatp
;
1058 curr_linkp
->odatp
= curr_odatp
;
1059 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
1060 // curr_linkp->ele_idx = -1;
1064 /* Svlinks dont have animation names */
1070 struct cdat
* curr_cdatp
;
1071 struct link
* curr_linkp
;
1073 curr_cdatp
= curr_cdat();
1074 curr_linkp
= alloc_link();
1076 /* Insert svlink into link_stack so that it gets processed at
1078 curr_linkp
->type
= 3;
1079 curr_linkp
->classp
= curr_cdatp
;
1080 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
1081 // curr_linkp->ele_idx = -1;
1082 curr_linkp
->link_t
.svlink
.refid
= refid
;
1086 /* At the point of reducing to a set, most of the
1087 sets odat information has already been populated
1088 during the reduction of its right hand side
1089 non terminals (hitbox, root, quad_list). */
1094 struct odat
* curr_odatp
;
1095 struct cdat
* curr_cdatp
;
1096 struct set
* curr_setp
;
1097 struct ref
* prev_refp
;
1098 struct ref
* curr_refp
;
1099 struct vdat
* curr_vdatp
;
1101 curr_odatp
= curr_set_odatp
; //allocated at insert_set_label
1102 curr_cdatp
= curr_cdat();
1103 curr_setp
= curr_set();
1104 prev_refp
= curr_ref();
1105 curr_refp
= alloc_ref();
1106 curr_vdatp
= curr_vdat();
1108 curr_vdatp
->creator
= curr_set_odatp
;
1110 curr_setp
->cdat_idx
= curr_cdatp
->idx
; //does a set need its class idx?
1111 u8_cpy(curr_setp
->name
, curr_odatp
->name
, 32);
1112 curr_cdatp
->num_sets
++;
1114 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
1115 curr_odatp
->refp
= curr_refp
;
1117 refid
= curr_setp
->refid
; // refid set by insert_set_label(name, refid)
1119 curr_refp
->refid
= refid
;
1120 curr_refp
->lastref
= prev_refp
;
1121 curr_refp
->odatp
= curr_odatp
;
1122 prev_refp
->nextref
= curr_refp
;
1127 /* Created as a seperate function, instead of setting the ODATS vdat_id and
1128 calling inc_vdat() inside of insert_set(), to account for the set reduction
1129 where a vdat is not created (o/v/svlinks). */
1134 struct vdat
* curr_vdatp
;
1136 curr_vdatp
= curr_vdat();
1138 curr_set_odatp
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
1139 curr_set_odatp
->vdatp
= curr_vdatp
;
1140 curr_set_odatp
= NULL
; //This sets odat shouldnt be modified after populating odats vdat info
1143 /* Populates the odat name and refid for odat, allocate the odat here for the rest of
1144 the functions to use via curr_odat(). */
1151 struct odat
* curr_odatp
;
1153 curr_odatp
= alloc_odat();
1155 u8_cpy(curr_odatp
->name
, name
, 32);
1156 curr_odatp
->map
[0] = 0;
1159 curr_odatp
->refid
= refid
;
1161 curr_odatp
->refid
= ss_refid
++;
1165 /* We don't make an odat here, at output time we will resolve
1166 the refid to the corresponding odat. */
1172 /* Do nothing because we already know the refid that
1173 the odat needs for this element (in the quad_file) */
1182 struct cdat
* curr_cdatp
;
1183 struct set
* curr_setp
;
1184 struct link
* curr_linkp
;
1186 curr_cdatp
= curr_cdat();
1187 curr_setp
= curr_set();
1188 curr_linkp
= alloc_link();
1190 /* Insert vlink into link_stack so that it gets processed at
1192 curr_linkp
->classp
= curr_cdatp
;
1193 curr_linkp
->type
= 2;
1194 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
1195 //curr_linkp->ele_idx = curr_setp->num_ele;
1196 curr_linkp
->link_t
.vlink
.refid
= refid
;
1197 u8_cpy(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
1206 struct cdat
* curr_cdatp
;
1207 struct set
* curr_setp
;
1208 struct link
* curr_linkp
;
1210 curr_cdatp
= curr_cdat();
1211 curr_setp
= curr_set();
1212 curr_linkp
= alloc_link();
1214 curr_linkp
->classp
= curr_cdatp
;
1215 curr_linkp
->type
= 3;
1217 //curr_linkp->ele_idx = curr_setp->num_ele;
1218 curr_linkp
->link_t
.svlink
.refid
= refid
;
1223 //Insert element into odat_buf and cdatpages
1228 struct cdat
* curr_cdatp
;
1229 struct odat
* curr_odatp
;
1230 struct vdat
* curr_vdatp
;
1231 struct set
* curr_setp
;
1232 struct ele
* curr_elep
;
1233 struct ref
* curr_refp
;
1234 struct ref
* prev_refp
;
1237 curr_odatp
= curr_odat(); //malloced @ insert_ele_label
1238 curr_vdatp
= curr_vdat();
1239 curr_setp
= curr_set();
1240 prev_refp
= curr_ref();
1241 curr_refp
= alloc_ref();
1243 curr_vdatp
->creator
= curr_odatp
;
1245 /* Populate odat for ele */
1246 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
1247 curr_odatp
->refp
= curr_refp
;
1248 curr_odatp
->parent_odatp
= curr_set_odatp
;
1250 refid
= curr_odatp
->refid
;
1252 curr_refp
->refid
= refid
;
1253 curr_refp
->lastref
= prev_refp
;
1254 curr_refp
->odatp
= curr_odatp
;
1255 prev_refp
->nextref
= curr_refp
;
1262 { struct odat
* curr_odatp
;
1263 curr_odatp
= curr_odat();
1264 curr_odatp
->vdat_id
= num_vdats
;
1276 /* ( int x, int y, int z, int refid */
1279 /* struct quad* curr_quadp; */
1281 /* curr_quadp = curr_quad(); */
1283 /* curr_quadp->x = x; */
1284 /* curr_quadp->y = y; */
1285 /* curr_quadp->z = z; */
1286 /* curr_quadp->refid = refid; */
1292 /* /\* serting the hitbox into the set */
1293 /* odat. Elements that don't have */
1294 /* a hitbox will use the sets root. *\/ */
1299 /* { struct odat* curr_odatp; */
1301 /* curr_odatp = curr_odat(); */
1302 /* curr_odatp->hitbox = hitbox; */
1305 /* /\* Inserting the root into the set */
1306 /* odat. Elements that don't have */
1307 /* a root will use the sets root. *\/ */
1314 /* { struct odat* curr_odatp; */
1316 /* curr_odatp = curr_odat(); */
1317 /* curr_odatp->root.x = x; */
1318 /* curr_odatp->root.y = y; */
1319 /* curr_odatp->root.z = z; */
1326 /* insert_frame_pointer */
1327 /* ( uint8_t direction, */
1330 /* { struct model* curr_modelp; */
1332 /* curr_modelp = curr_model(); */
1334 /* curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */