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