merging
[henge/apc.git] / src / ir.c
1 /*!@file
2 \brief IR Memory Implementation
3 \details Intermediary memory management
4 \author Jordan Lavatai
5 \date Aug 2016
6 ----------------------------------------------------------------------------*/
7 #include <stdlib.h>
8 #include <stdio.h>
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
14 #include "apc.h"
15
16
17 extern
18 int
19 name_u8_cpy(struct name*, struct name*);
20
21 extern
22 int
23 name_u8_cmp(struct name*, struct name*);
24
25 extern
26 int
27 name_u8_set(struct name*, ucs4_t);
28
29 int
30 ir_init(void);
31 struct cdat*
32 alloc_cdat(void);
33 struct odat*
34 alloc_odat(void);
35 void
36 alloc_vdat(void);
37 struct link*
38 alloc_link(void);
39 struct ref*
40 alloc_ref(void);
41 struct set*
42 alloc_set(void);
43 struct cdat*
44 curr_cdat(void);
45 struct odat*
46 curr_odat(void);
47 struct vdat*
48 curr_vdat(void);
49 struct map*
50 curr_map(void);
51 struct set*
52 curr_cdat_set(void);
53 struct set*
54 curr_set(int);
55 struct ref*
56 curr_ref(void);
57 struct model*
58 curr_model(void);
59
60 /* ir.c */
61 void
62 inc_posts(void);
63 void
64 push_cdat(struct name*);
65 void
66 pop_cdat(void);
67 void
68 insert_refid(int);
69 void
70 insert_link_name(struct name*);
71 void
72 insert_link_namelist(struct name*);
73 void
74 insert_ss_name(struct name*);
75 void
76 insert_ss_namelist(struct name*);
77 void
78 insert_mlink(struct name*, int);
79 void
80 insert_vlink(struct name*, int);
81 void
82 insert_ref(struct odat*, int);
83 void
84 alloc_vdat(void);
85 void
86 insert_vdat(void);
87 void
88 insert_map(struct name*, int, int, int, int, uint8_t*);
89 void
90 insert_framesheet(struct name*, int, int, int, int, uint8_t*);
91
92
93
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) \
107 { int i; \
108 (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \
109 (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \
110 CSP_PUSH(STACK); \
111 for( i = 0; i < MAX_CHUNKS; i++){ \
112 (STACK).dsp[i] += pagesize; \
113 } \
114 }
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))
152 //Metadata
153 #define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models])
154
155
156
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 */
174 struct cdat {
175 struct name name;
176 int idx;
177 int num_classes;
178 int num_sets;
179 struct cdat* class_list[MAX_CLASSES];
180 struct set* set_list[MAX_SETS];
181 };
182
183
184 /* Sets: What is a set?
185 Instantiation?
186 Associations?
187 Containment?
188 Usage?
189 The set is populated at parse time AFTER the elements are populated, due to
190 the nature of bottom up parsing. */
191 struct set {
192 int cdat_idx;
193 int num_sets;
194 struct set* set_list[MAX_SETS];
195 };
196
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
205 a random access. */
206
207 struct ref {
208 int type; //TODO: Is this needed?
209 struct ref* nextref;
210 struct ref* lastref;
211 struct odat* odatp;
212 int refid; //0xFFFFFF->digit
213 };
214
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
225 was linked */
226
227 /* TODO: Explain links more betta */
228
229 struct olink {
230 int src_refid;
231 };
232
233 struct vlink {
234 int src_refid;
235 struct name src_animname;
236 struct name src_namelist[MAX_DEPTH];
237 };
238
239 struct mlink {
240 int src_refid;
241 struct name src_mapname;
242 struct name src_namelist[MAX_DEPTH];
243
244 };
245
246 union link_t {
247 struct vlink vlink;
248 struct mlink mlink;
249 struct olink olink;
250 };
251
252
253 /* From: src odat ()To: dest odat (refid)*/
254 struct link {
255 int type; //1 = olink, 2 = vlink, 3 = mlink
256 union link_t link_t;
257 int dest_refid; //if it exists
258 struct odat* dest_odatp;
259
260 };
261
262 struct map {
263 struct name name;
264 int height;
265 int width;
266 uint8_t filepath[FPATH_MAX];
267 };
268
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*/
275 struct odat {
276 struct name name;
277 int refid;
278 int ismap;
279 int vdat_idx;
280 struct link* linkp;
281 struct vdat* vdatp;
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
285
286 };
287
288 /* A framesheet is a grouping of animation frames in
289 a single direction (N,W,S,E) */
290 struct framesheet {
291 int width;
292 int height;
293 int num_frames;
294
295 };
296
297 /* A model is a collection of framesheets for every
298 direction (N,W,S,E,NW,NE,SW,SE)*/
299 /* NAMED spritesheet */
300 struct model {
301 struct name name;
302 uint8_t filepath[PATH_MAX];
303 struct framesheet spritesheet[8]; //one for each
304 };
305
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*/
311 struct vdat {
312 struct odat* creator; //pointer to odat that made this vdat
313 int num_models;
314 uint8_t filename[FNAME_MAX];
315 int height;
316 int width;
317 uint8_t filepath[FPATH_MAX];
318 struct model model_list[MAX_MODELS];
319 };
320
321
322 struct set_frame
323 { struct name namelist[MAX_DEPTH];
324 int num_names;
325 struct set* setp;
326 struct odat* odatp;
327 } ;
328
329
330
331 struct set_stack
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
334 };
335
336
337 //"type free" chunk stacking
338 struct chunk_stack
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
345
346
347
348
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. */
355
356
357 struct cdat* cdat_stack[MAX_CLASSES];
358 struct cdat** cdat_stackp;
359
360 struct set_stack ss;
361 struct name set_namelist[MAX_DEPTH];
362 int set_numnames = 0;
363
364 struct name link_namelist[MAX_DEPTH];
365 int link_numnames = 0;
366
367 int num_cdats = 0;
368 int num_odats = 0;
369 int num_vdats = 0;
370 int num_sets = 0;
371 int num_refs = 0;
372 int ss_refid = 0x0FFFFFFF; /* system space for refids */
373 int num_posts = 0;
374 int num_links = 0;
375 int num_models = 0;
376 long pagesize = 0;
377
378
379 /* The initalization function of the IR. */
380 int
381 ir_init()
382 { struct name name;
383
384
385 uint8_t root[4] = "root";
386
387 u8_stpncpy(name.name, root, 4);
388
389 pagesize = sysconf(_SC_PAGESIZE);
390
391 INIT_CDAT();
392 *cdat_stackp = CURRENT_CDAT();
393 name_u8_cpy(&(*cdat_stackp)->name, &name);
394
395 INIT_ODAT();
396 INIT_VDAT();
397 VDAT_ALLOC(); //NULL vdat
398 VDAT_ALLOC(); //First vdat req. because alloc_vdat happens after vdat is reduced
399 INIT_SET();
400 INIT_LINK();
401 INIT_REF();
402 INIT_POST();
403
404
405 return 0;
406
407 }
408
409 void
410 ir_quit()
411 {
412 int i;
413
414 for(i = 0; i < CHUNKS_LEN(ccs) ; i++)
415 {
416 free(ccs.chunks[i]);
417 }
418 for(i = 0; i < CHUNKS_LEN(ocs); i++)
419 {
420 free(ocs.chunks[i]);
421 }
422 for(i = 0; i < CHUNKS_LEN(vcs) ; i++)
423 {
424 free(vcs.chunks[i]);
425 }
426 for(i = 0; i < CHUNKS_LEN(rcs); i++)
427 {
428 free(rcs.chunks[i]);
429 }
430 for(i = 0; i < CHUNKS_LEN(lcs); i++)
431 {
432 free(lcs.chunks[i]);
433 }
434 for(i = 0; i < CHUNKS_LEN(pcs); i++)
435 {
436 free(pcs.chunks[i]);
437 }
438
439 }
440
441 struct cdat*
442 alloc_cdat()
443 {
444 num_cdats++;
445 if(CDAT_FULL())
446 { if(CCS_FULL())
447 { fprintf(stderr, "You have allocated to many (%d) cdats ", num_cdats);
448 exit(EXIT_FAILURE);
449 }
450 else
451 CSP_PUSH(ccs);
452 }
453 else
454 CDAT_ALLOC();
455
456 return CURRENT_CDAT();
457 }
458
459 //these should probably be inline
460 struct odat*
461 alloc_odat
462 ()
463 {
464 num_odats++;
465 if(ODAT_FULL())
466 { if(!OCS_FULL())
467 { fprintf(stderr, "You have allocated to many (%d) odats ", num_odats);
468 exit(EXIT_FAILURE);
469 }
470 else
471 CSP_PUSH(ocs);
472 }
473 else
474 ODAT_ALLOC();
475
476 return CURRENT_ODAT();
477 }
478
479 void
480 alloc_vdat
481 ()
482 { num_vdats++;
483 if(VDAT_FULL())
484 { if(!VCS_FULL())
485 { fprintf(stderr, "You have allocated to many (%d) vdats ", num_vdats);
486 exit(EXIT_FAILURE);
487 }
488 else
489 CSP_PUSH(vcs);
490 }
491 else
492 VDAT_ALLOC();
493
494
495 }
496
497 struct set*
498 alloc_set
499 ()
500 { num_sets++;
501 if(SET_FULL())
502 { if(!SCS_FULL())
503 { fprintf(stderr, "You have allocated to many (%d) sets ", num_sets);
504 exit(EXIT_FAILURE);
505 }
506 else
507 CSP_PUSH(scs);
508 }
509 else
510 SET_ALLOC();
511
512 return CURRENT_SET();
513 }
514
515
516 struct link*
517 alloc_link
518 ()
519 { num_links++;
520 if(LDAT_FULL())
521 { if(!LCS_FULL())
522 { fprintf(stderr, "You have allocated to many (%d) links ", num_links);
523 exit(EXIT_FAILURE);
524 }
525 else
526 CSP_PUSH(lcs);
527 }
528 else
529 LDAT_ALLOC();
530
531 return CURRENT_LINK();
532
533 }
534
535 struct ref*
536 alloc_ref
537 ()
538 { num_refs++;
539 if(REF_FULL())
540 { if(!RCS_FULL())
541 { fprintf(stderr, "You have allocated to many (%d) refs ", num_refs);
542 exit(EXIT_FAILURE);
543 }
544 else
545 CSP_PUSH(rcs);
546 }
547 else
548 REF_ALLOC();
549
550
551 if(num_refs % 16 == 0)
552 { CURRENT_POST() = CURRENT_REF();
553 inc_posts();
554 }
555
556 return CURRENT_REF();
557 }
558
559 void
560 inc_posts()
561 { num_posts++;
562 if(POST_FULL())
563 { if(!PCS_FULL())
564 { fprintf(stderr, "You have allocated to many (%d) refs ", num_posts);
565 exit(EXIT_FAILURE);
566 }
567 else
568 CSP_PUSH(pcs);
569 }
570 else
571 POST_ALLOC();
572
573 }
574
575 struct cdat*
576 curr_cdat
577 ()
578 {
579 return (*cdat_stackp);
580 }
581
582 struct odat*
583 curr_odat
584 ()
585 {
586 return CURRENT_ODAT();
587 }
588
589 struct vdat*
590 curr_vdat
591 ()
592 {
593 return CURRENT_VDAT();
594 }
595
596 struct set*
597 curr_cdat_set
598 ()
599 {
600 return CURRENT_SET();
601 }
602
603 struct set*
604 curr_set
605 (int depth)
606 { int i;
607 struct set* setp;
608
609 for(i = 0; i <= depth; i++)
610 { if(!(setp = setp->set_list[setp->num_sets]))
611 { printf("You are trying to access a set that does not exist irmem.c\n");
612 return NULL;
613 }
614 }
615
616
617 return setp;
618 }
619
620 struct ref*
621 curr_ref
622 ()
623 {
624 return CURRENT_REF();
625 }
626 struct ref*
627 prev_ref
628 ()
629 {
630 return PREVIOUS_REF();
631 }
632 struct model*
633 curr_model
634 ()
635 {
636 return &CURRENT_MODEL();
637 }
638
639 /* IR.C*/
640 void
641 push_cdat
642 ( name )
643 struct name* name;
644 {
645 struct cdat* curr_cdatp;
646
647 curr_cdatp = alloc_cdat();
648
649 name_u8_cpy(&curr_cdatp->name, name);
650 curr_cdatp->idx = num_cdats;
651
652 /* Set the cdat as a subclass of the previous cdat */
653 (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes] = curr_cdatp;
654 /* Push the cdat onto the cdat_stack */
655 *++cdat_stackp = curr_cdatp;
656
657 }
658
659 void
660 pop_cdat
661 ()
662 {
663 cdat_stackp--;
664 }
665
666
667 void
668 insert_set_name
669 ( name )
670 struct name* name;
671 {
672 //Push name onto current namelist, set the set_namelist.
673 name_u8_cpy(&set_namelist[set_numnames++], name);
674
675
676 }
677
678
679 void
680 insert_set_namelist
681 ( name )
682 struct name* name;
683 { int depth, nameidx, i;
684
685 insert_set_name(name);
686
687 //Check if entire string matches first? Only possible if namelist is contiguous (uint8_t strings seperated by \0)
688 //Create odats/sets for each name in namelist where nameidx > ns_depth
689 //first check if any parts of namelist matches what is currently on namestack
690 //we can gauruntee that from ns_depth + 1 -> set_numnames namelists dont match. x
691
692
693 //if name_list doesnt match, from the first depth at which namelist doesnt match
694 //remove the nameframes namelist (zero out ones below?) and replace with current namelist,
695 //then allocate a new odat and set it to the current set_frame.
696 for( depth = 0; depth < set_numnames ; depth++ )
697 { for (nameidx = 0; nameidx <= depth; nameidx++)
698 { if( name_u8_cmp(&set_namelist[nameidx], &ss.set_frames[depth].namelist[nameidx]) != 0 )
699 { /* Populate the namelist of the set at the current depth */
700 for(i = 0; i <= depth; i++)
701 name_u8_cpy(&ss.set_frames[depth].namelist[i], &set_namelist[i]);
702
703 /* Alloc set and odat */
704 ss.set_frames[depth].odatp = alloc_odat();
705 ss.set_frames[depth].setp = alloc_set();
706
707 /* populate set/odat name and cdat_idx */
708 name_u8_cpy(&ss.set_frames[depth].odatp->name, &set_namelist[depth]);
709 ss.set_frames[depth].setp->cdat_idx = ( *cdat_stackp)->idx;
710
711 /* Insert allocated set and odat into their respective trees if there is a depth
712 (they have parents) */
713 if(depth)
714 { ss.set_frames[depth].odatp->parent_odatp = ss.set_frames[depth-1].odatp;
715 if(ss.set_frames[depth-1].setp->num_sets < MAX_SETS)
716 ss.set_frames[depth-1].setp->set_list[ss.set_frames[depth-1].setp->num_sets++] = ss.set_frames[depth].setp;
717 else
718 { printf("you have allocated too many sets in insert_namelist()\n");
719 //TODO: EXIT()
720 }
721 }
722 else /* no parent set, so assign to cdat set_list */
723 { ss.set_frames[depth].odatp->parent_odatp = NULL; //no parent odat = NULL.
724 if(curr_cdat_set()->num_sets < MAX_SETS)
725 curr_cdat_set()->set_list[curr_cdat_set()->num_sets++] = ss.set_frames[depth].setp;
726 else
727 { printf("you have allocated too many sets in insert_namelist()\n");
728 //TODO: EXIT()
729 }
730 }
731
732
733 ss.set_frames[depth].num_names = set_numnames;
734 ss.curr_depth = depth;
735 }
736
737 }
738
739 }
740 }
741
742 /*. We create new odats for each map variant that are children of the current odat/set
743 , set their name as the map name, and identify them by marking them as a map. This lets
744 us distinguish between sibling odatsthat have the same name because the map of the parent
745 odat had the same name as another, regular odat*/
746 #define CURR_SS_FRAME() (ss.set_frames[ss.curr_depth])
747 #define CURR_SS_SETP() (CURR_SS_FRAME().setp)
748 #define CURR_SS_ODATP() (CURR_SS_FRAME().odatp)
749 void
750 insert_map
751 ( name, direction, height, width, refid, filepath )
752 struct name* name;
753 int direction, height, width, refid;
754 uint8_t* filepath;
755 { int i;
756 struct odat* curr_mem_odatp; //pointer to odat in odat_buf
757 struct set* curr_mem_setp; //pointer to set in set_buf
758 struct link* linkp;
759
760 curr_mem_odatp = alloc_odat();
761 curr_mem_setp = alloc_set();
762 //Create a new odat, make its parent be the set. Make a set for mdat, its name should
763 //be the name of the odat + name of model. That makes a conflict beween odats that are named
764 //the same thing as the model of a sibling odat that was created from a map. They can have
765 //same name if the map odat is marked. So mark the map odat.
766
767 //insert parent odat
768 curr_mem_odatp->parent_odatp = CURR_SS_ODATP();
769 //insert into set_list
770 if(CURR_SS_SETP()->num_sets < MAX_SETS)
771 CURR_SS_SETP()->set_list[CURR_SS_SETP()->num_sets++] = curr_mem_setp;
772 else
773 { printf("You have allocated to many sets, error in insert_map()\n");
774 //TODO: EXIT()
775 }
776
777 //indicate that newly created odat is a map
778 curr_mem_odatp->ismap = 1;
779 //set odat and set name
780 name_u8_cpy(&curr_mem_odatp->name, name);
781
782 /* set cdat idx values for both set and odat */
783 curr_mem_setp->cdat_idx = num_cdats;
784
785 /* TODO: INSERT MAP HEIGHT/WIDTH/NAME/FILEPATH INTO ODAT */
786
787
788 /* Generate refid if needed, put into ref_buf */
789 if(!refid)
790 refid = ss_refid++;
791
792 insert_ref(curr_mem_odatp, refid);
793
794 /* If current odatp on stack has a link, then we need to make our own link. just set the vdat_idx */
795 if(CURR_SS_ODATP()->vdat_idx == 0)
796 { //alloc a link
797 linkp = alloc_link();
798 linkp->type = CURR_SS_ODATP()->linkp->type;
799 linkp->dest_odatp = CURR_SS_ODATP();
800 linkp->dest_refid = refid;
801 linkp->link_t.mlink.src_refid = CURR_SS_ODATP()->linkp->link_t.mlink.src_refid;
802
803 /* Copy the animation name of the vlink*/
804 name_u8_cpy(&linkp->link_t.vlink.src_animname, &CURR_SS_ODATP()->linkp->link_t.vlink.src_animname);
805 /* Copy the namelist of the vlink*/
806 for(i = 0; i < MAX_DEPTH; i++)
807 name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &CURR_SS_ODATP()->linkp->link_t.vlink.src_namelist[i]);
808 }
809 else
810 curr_mem_odatp->vdat_idx = CURR_SS_ODATP()->vdat_idx;
811
812
813
814
815 }
816
817
818 /* 11/22 Each vdat has a multiple models. Each model has 8 framesheets, one in each
819 direction, that create a spritesheet. Inserting framesheets into the correct
820 model is just a matter of checking whether or not the last models name matches
821
822 the current one. We can never get a framesheet that is for the same model before
823 AND after some other model, due to alphasorting of the files in each directory */
824 void
825 insert_framesheet
826 ( model_name, direction, height, width, refid, filepath )
827 struct name* model_name;
828 int direction, height, width, refid;
829 uint8_t* filepath;
830 { struct vdat* curr_vdatp;
831 struct model* curr_modelp;
832 static struct name last_model_name[32];
833
834
835 curr_vdatp = curr_vdat();
836
837 /* If the model name changed, that means there are no more
838 framesheets for that model to be processed, a guaruntee we make
839 b/c the filenames are alphabetically sorted */
840 if(!name_u8_cmp(last_model_name, model_name))
841 { if(curr_vdatp->num_models)
842 curr_vdatp->num_models++;
843 num_models++; // total number of models
844 }
845
846
847 if(CURR_SS_ODATP()->refid == 0)
848 { if(!refid)
849 refid = ss_refid++;
850 insert_ref(CURR_SS_ODATP(), refid);//given a odatp and a refid, insert the odatp into the ref_buf.
851 //push ref into ref_buf.
852 }
853 else
854 printf("error: redefining a previously set refid\n");
855
856 curr_modelp = curr_model();
857
858 name_u8_cpy(&curr_modelp->name, model_name);
859 curr_modelp->spritesheet[direction].height = height;
860 curr_modelp->spritesheet[direction].width = width;
861 /* TODO: INSERT FILEPATH INTO VDAT */
862 u8_stpncpy(curr_modelp->spritesheet[direction].filepath, filepath, FPATH_MAX);
863
864 name_u8_cpy(last_model_name, model_name);
865
866
867 }
868
869
870
871 //src_path is stored in link_namelist
872 void
873 insert_mlink
874 ( src_mapname, src_refid)
875 struct name* src_mapname;
876 int src_refid;
877 { struct link* linkp;
878 int i;
879
880 linkp = alloc_link();
881
882 /* set type */
883 linkp->type = 3;
884 /* set the name of the src map for the link, if a name exists */
885 if(src_mapname)
886 name_u8_cpy(&linkp->link_t.mlink.src_mapname, src_mapname);
887 /* Set the source ref id of the link */
888 linkp->link_t.mlink.src_refid = src_refid;
889 /* Copy the entire namelist of the link, if it exists */
890 for(i = 0; i < link_numnames; i--) //TODO MAX_DEPTH -> link_namelist_num??
891 { name_u8_cpy(&linkp->link_t.mlink.src_namelist[i], &link_namelist[i]);
892 name_u8_set(&link_namelist[i], (ucs4_t) 0);
893 }
894 link_numnames = 0;
895
896 linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack
897
898 }
899
900 void
901 insert_link_name
902 ( name )
903 struct name* name;
904 {
905 //Push name onto current namelist, set the set_namelist.
906 name_u8_cpy(&link_namelist[link_numnames++], name);
907
908 }
909
910 /* Nearly identical to mlink */
911 void
912 insert_vlink
913 ( src_animname, src_refid )
914 struct name* src_animname;
915 int src_refid;
916 { struct link* linkp;
917 int i;
918
919 linkp = alloc_link();
920
921 /* set type */
922 linkp->type = 2;
923
924 /* set the name of the src animname for the link, if a name exists */
925 if(src_animname)
926 name_u8_cpy(&linkp->link_t.vlink.src_animname, src_animname);
927
928 /* Set the source ref id of the link */
929 linkp->link_t.mlink.src_refid = src_refid;
930
931 /* Copy the entire namelist of the link, if it exists */
932 for(i = 0; i < link_numnames; i++) //TODO MAX_DEPTH -> link_namelist_num??
933 { name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &link_namelist[i]);
934 name_u8_set(&link_namelist[i], (ucs4_t) 0);//set to null for next link_namelist
935 }
936
937 linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack
938
939 }
940
941
942 /* TODO: Do we really need to store the prev/next pointer? iterating through the
943 ref_buf could be achieved by iterating until the num_refs anyway. */
944 void
945 insert_ref
946 ( odatp, refid )
947 struct odat* odatp;
948 int refid;
949 { struct ref* curr_refp;
950 struct ref* prev_refp;
951
952 curr_refp = alloc_ref();
953 prev_refp = prev_ref();
954
955 prev_refp->nextref = curr_refp;
956 curr_refp->lastref = prev_refp;
957
958 curr_refp->odatp = odatp;
959 curr_refp->refid = refid;
960
961 if(refid % 16)
962 { POST_ALLOC();
963 CURRENT_POST()->refid = refid;
964 CURRENT_POST()->odatp = odatp;
965 }
966
967
968
969 }
970
971 void
972 insert_vdat
973 ()
974 { struct vdat* curr_vdatp;
975
976 curr_vdatp = curr_vdat();
977
978 curr_vdatp->creator = CURR_SS_ODATP();
979 CURR_SS_ODATP()->vdat_idx = num_vdats;
980 CURR_SS_ODATP()->vdatp = curr_vdatp;
981 alloc_vdat();
982 }
983
984 void
985 insert_refid
986 ( refid )
987 int refid;
988 { CURR_SS_ODATP()->refid = refid;
989 }
990 #if 0
991
992
993 /* Called in the reduction of a set. While both odats (eles and sets)
994 have identical label terminals, we are unable to give a single grammatical rule
995 for both due to how we allocate odats in the odat buf. Due to the
996 nature of bottom up parsing, the set label is recognized first, and then the
997 sets elements are recognized. This means that after we have processed the sets elemenets,
998 the curr_odat is going to be the last element and NOT the set that was first allocated.
999 To get around this, we create a global variable set_odatp that will store the pointer
1000 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
1001 have access to it. Curr set points the sets representation in the cdat, curr_set_odatp
1002 points to the sets representation as an odat*/
1003
1004 //TODO: Add insert_set_ref()
1005 //TODO: Is this the correct allocation scheme? No do the one ken suggested
1006 void
1007 insert_s_name
1008 ( struct name* name
1009 )
1010 {
1011
1012 struct set* curr_setp;
1013
1014 curr_setp = curr_set();
1015 curr_set_odatp = alloc_odat();
1016
1017 u8_cpy(curr_set_odatp->name, name, 32);
1018 u8_cpy(curr_setp->name, name, 32);
1019 curr_set_odatp->parent_odatp = NULL;
1020
1021
1022 }
1023
1024 /* Inserting a olink instead of a set. Set is really just a placeholder
1025 for another set. Allocate the memory for the set so taht it can be populated*/
1026 void
1027 insert_set_olink
1028 ( int refid
1029 )
1030 {
1031 struct set* curr_setp;
1032
1033 curr_setp = curr_set();
1034
1035 curr_setp->refid = refid;
1036
1037 }
1038
1039 void
1040 insert_set_vlink
1041 ( int refid,
1042 uint8_t* anim_name
1043 )
1044 {
1045 struct cdat* curr_cdatp;
1046 struct odat* curr_odatp;
1047 struct link* curr_linkp;
1048
1049
1050 curr_cdatp = curr_cdat();
1051 curr_odatp = curr_odat();
1052 curr_linkp = alloc_link();
1053
1054 /* Insert vlink into link_stack so that it gets processed at
1055 output time */
1056 curr_linkp->type = 2;
1057 /* Store the target odat information*/
1058 curr_linkp->link_t.vlink.refid = refid;
1059 u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32);
1060 /* Store the linking odat/cdat information */
1061 curr_linkp->classp = curr_cdatp;
1062 curr_linkp->odatp = curr_odatp;
1063 curr_linkp->set_idx = curr_cdatp->num_sets;
1064 // curr_linkp->ele_idx = -1;
1065
1066 }
1067
1068 /* Svlinks dont have animation names */
1069 void
1070 insert_set_svlink
1071 ( int refid
1072 )
1073 {
1074 struct cdat* curr_cdatp;
1075 struct link* curr_linkp;
1076
1077 curr_cdatp = curr_cdat();
1078 curr_linkp = alloc_link();
1079
1080 /* Insert svlink into link_stack so that it gets processed at
1081 output time */
1082 curr_linkp->type = 3;
1083 curr_linkp->classp = curr_cdatp;
1084 curr_linkp->set_idx = curr_cdatp->num_sets;
1085 // curr_linkp->ele_idx = -1;
1086 curr_linkp->link_t.svlink.refid = refid;
1087
1088 }
1089
1090 /* At the point of reducing to a set, most of the
1091 sets odat information has already been populated
1092 during the reduction of its right hand side
1093 non terminals (hitbox, root, quad_list). */
1094 void
1095 insert_set
1096 ()
1097 { int refid;
1098 struct odat* curr_odatp;
1099 struct cdat* curr_cdatp;
1100 struct set* curr_setp;
1101 struct ref* prev_refp;
1102 struct ref* curr_refp;
1103 struct vdat* curr_vdatp;
1104
1105 curr_odatp = curr_set_odatp; //allocated at insert_set_label
1106 curr_cdatp = curr_cdat();
1107 curr_setp = curr_set();
1108 prev_refp = curr_ref();
1109 curr_refp = alloc_ref();
1110 curr_vdatp = curr_vdat();
1111
1112 curr_vdatp->creator = curr_set_odatp;
1113
1114 curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx?
1115 u8_cpy(curr_setp->name, curr_odatp->name, 32);
1116 curr_cdatp->num_sets++;
1117
1118 curr_odatp->cdat_idx = curr_cdatp->idx;
1119 curr_odatp->refp = curr_refp;
1120
1121 refid = curr_setp->refid; // refid set by insert_set_label(name, refid)
1122
1123 curr_refp->refid = refid;
1124 curr_refp->lastref = prev_refp;
1125 curr_refp->odatp = curr_odatp;
1126 prev_refp->nextref = curr_refp;
1127
1128
1129
1130 }
1131 /* Created as a seperate function, instead of setting the ODATS vdat_id and
1132 calling inc_vdat() inside of insert_set(), to account for the set reduction
1133 where a vdat is not created (o/v/svlinks). */
1134 void
1135 insert_set_vdatid
1136 ()
1137 {
1138 struct vdat* curr_vdatp;
1139
1140 curr_vdatp = curr_vdat();
1141
1142 curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks
1143 curr_set_odatp->vdatp = curr_vdatp;
1144 curr_set_odatp = NULL; //This sets odat shouldnt be modified after populating odats vdat info
1145 }
1146
1147 /* Populates the odat name and refid for odat, allocate the odat here for the rest of
1148 the functions to use via curr_odat(). */
1149 void
1150 insert_ele_label
1151 ( uint8_t* name,
1152 int refid
1153 )
1154 {
1155 struct odat* curr_odatp;
1156
1157 curr_odatp = alloc_odat();
1158
1159 u8_cpy(curr_odatp->name, name, 32);
1160 curr_odatp->map[0] = 0;
1161
1162 if(refid != -1)
1163 curr_odatp->refid = refid;
1164 else
1165 curr_odatp->refid = ss_refid++;
1166
1167 }
1168
1169 /* We don't make an odat here, at output time we will resolve
1170 the refid to the corresponding odat. */
1171 void
1172 insert_ele_olink
1173 ( int refid
1174 )
1175 {
1176 /* Do nothing because we already know the refid that
1177 the odat needs for this element (in the quad_file) */
1178 }
1179
1180 void
1181 insert_ele_vlink
1182 ( int refid,
1183 uint8_t* anim_name
1184 )
1185 {
1186 struct cdat* curr_cdatp;
1187 struct set* curr_setp;
1188 struct link* curr_linkp;
1189
1190 curr_cdatp = curr_cdat();
1191 curr_setp = curr_set();
1192 curr_linkp = alloc_link();
1193
1194 /* Insert vlink into link_stack so that it gets processed at
1195 output time */
1196 curr_linkp->classp = curr_cdatp;
1197 curr_linkp->type = 2;
1198 curr_linkp->set_idx = curr_cdatp->num_sets;
1199 //curr_linkp->ele_idx = curr_setp->num_ele;
1200 curr_linkp->link_t.vlink.refid = refid;
1201 u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32);
1202
1203 }
1204
1205 void
1206 insert_ele_svlink
1207 ( int refid
1208 )
1209 {
1210 struct cdat* curr_cdatp;
1211 struct set* curr_setp;
1212 struct link* curr_linkp;
1213
1214 curr_cdatp = curr_cdat();
1215 curr_setp = curr_set();
1216 curr_linkp = alloc_link();
1217
1218 curr_linkp->classp = curr_cdatp;
1219 curr_linkp->type = 3;
1220
1221 //curr_linkp->ele_idx = curr_setp->num_ele;
1222 curr_linkp->link_t.svlink.refid = refid;
1223
1224
1225 }
1226
1227 //Insert element into odat_buf and cdatpages
1228 void
1229 insert_ele()
1230 {
1231 int refid;
1232 struct cdat* curr_cdatp;
1233 struct odat* curr_odatp;
1234 struct vdat* curr_vdatp;
1235 struct set* curr_setp;
1236 struct ele* curr_elep;
1237 struct ref* curr_refp;
1238 struct ref* prev_refp;
1239
1240
1241 curr_odatp = curr_odat(); //malloced @ insert_ele_label
1242 curr_vdatp = curr_vdat();
1243 curr_setp = curr_set();
1244 prev_refp = curr_ref();
1245 curr_refp = alloc_ref();
1246
1247 curr_vdatp->creator = curr_odatp;
1248
1249 /* Populate odat for ele */
1250 curr_odatp->cdat_idx = curr_cdatp->idx;
1251 curr_odatp->refp = curr_refp;
1252 curr_odatp->parent_odatp = curr_set_odatp;
1253
1254 refid = curr_odatp->refid;
1255
1256 curr_refp->refid = refid;
1257 curr_refp->lastref = prev_refp;
1258 curr_refp->odatp = curr_odatp;
1259 prev_refp->nextref = curr_refp;
1260
1261 }
1262
1263 void
1264 insert_ele_vdatid
1265 ()
1266 { struct odat* curr_odatp;
1267 curr_odatp = curr_odat();
1268 curr_odatp->vdat_id = num_vdats;
1269 }
1270
1271
1272
1273 #endif
1274
1275
1276
1277
1278 /* void */
1279 /* insert_quad */
1280 /* ( int x, int y, int z, int refid */
1281 /* ) */
1282 /* { */
1283 /* struct quad* curr_quadp; */
1284
1285 /* curr_quadp = curr_quad(); */
1286
1287 /* curr_quadp->x = x; */
1288 /* curr_quadp->y = y; */
1289 /* curr_quadp->z = z; */
1290 /* curr_quadp->refid = refid; */
1291
1292
1293
1294 /* } */
1295
1296 /* /\* serting the hitbox into the set */
1297 /* odat. Elements that don't have */
1298 /* a hitbox will use the sets root. *\/ */
1299 /* void */
1300 /* insert_hitbox */
1301 /* ( int hitbox */
1302 /* ) */
1303 /* { struct odat* curr_odatp; */
1304
1305 /* curr_odatp = curr_odat(); */
1306 /* curr_odatp->hitbox = hitbox; */
1307 /* } */
1308
1309 /* /\* Inserting the root into the set */
1310 /* odat. Elements that don't have */
1311 /* a root will use the sets root. *\/ */
1312 /* void */
1313 /* insert_root */
1314 /* ( int x, */
1315 /* int y, */
1316 /* int z */
1317 /* ) */
1318 /* { struct odat* curr_odatp; */
1319
1320 /* curr_odatp = curr_odat(); */
1321 /* curr_odatp->root.x = x; */
1322 /* curr_odatp->root.y = y; */
1323 /* curr_odatp->root.z = z; */
1324 /* } */
1325
1326
1327
1328
1329 /* void */
1330 /* insert_frame_pointer */
1331 /* ( uint8_t direction, */
1332 /* void* frame */
1333 /* ) */
1334 /* { struct model* curr_modelp; */
1335
1336 /* curr_modelp = curr_model(); */
1337
1338 /* curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */
1339 /* } */
1340