added everything to src
[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 printf("pagesize is %l\n", pagesize);
389
390 INIT_CDAT();
391 *cdat_stackp = CURRENT_CDAT();
392 name_u8_cpy(&(*cdat_stackp)->name, &name);
393
394 INIT_ODAT();
395 INIT_VDAT();
396 VDAT_ALLOC(); //NULL vdat
397 VDAT_ALLOC(); //First vdat req. because alloc_vdat happens after vdat is reduced
398 INIT_SET();
399 INIT_LINK();
400 INIT_REF();
401 INIT_POST();
402
403
404 return 0;
405
406 }
407
408 void
409 ir_quit()
410 {
411 int i;
412
413 for(i = 0; i < CHUNKS_LEN(ccs) ; i++)
414 {
415 free(ccs.chunks[i]);
416 }
417 for(i = 0; i < CHUNKS_LEN(ocs); i++)
418 {
419 free(ocs.chunks[i]);
420 }
421 for(i = 0; i < CHUNKS_LEN(vcs) ; i++)
422 {
423 free(vcs.chunks[i]);
424 }
425 for(i = 0; i < CHUNKS_LEN(rcs); i++)
426 {
427 free(rcs.chunks[i]);
428 }
429 for(i = 0; i < CHUNKS_LEN(lcs); i++)
430 {
431 free(lcs.chunks[i]);
432 }
433 for(i = 0; i < CHUNKS_LEN(pcs); i++)
434 {
435 free(pcs.chunks[i]);
436 }
437
438 }
439
440 struct cdat*
441 alloc_cdat()
442 {
443 num_cdats++;
444 if(CDAT_FULL())
445 { if(CCS_FULL())
446 { fprintf(stderr, "You have allocated to many (%d) cdats ", num_cdats);
447 exit(EXIT_FAILURE);
448 }
449 else
450 CSP_PUSH(ccs);
451 }
452 else
453 CDAT_ALLOC();
454
455 return CURRENT_CDAT();
456 }
457
458 //these should probably be inline
459 struct odat*
460 alloc_odat
461 ()
462 {
463 num_odats++;
464 if(ODAT_FULL())
465 { if(!OCS_FULL())
466 { fprintf(stderr, "You have allocated to many (%d) odats ", num_odats);
467 exit(EXIT_FAILURE);
468 }
469 else
470 CSP_PUSH(ocs);
471 }
472 else
473 ODAT_ALLOC();
474
475 return CURRENT_ODAT();
476 }
477
478 void
479 alloc_vdat
480 ()
481 { num_vdats++;
482 if(VDAT_FULL())
483 { if(!VCS_FULL())
484 { fprintf(stderr, "You have allocated to many (%d) vdats ", num_vdats);
485 exit(EXIT_FAILURE);
486 }
487 else
488 CSP_PUSH(vcs);
489 }
490 else
491 VDAT_ALLOC();
492
493
494 }
495
496 struct set*
497 alloc_set
498 ()
499 { num_sets++;
500 if(SET_FULL())
501 { if(!SCS_FULL())
502 { fprintf(stderr, "You have allocated to many (%d) sets ", num_sets);
503 exit(EXIT_FAILURE);
504 }
505 else
506 CSP_PUSH(scs);
507 }
508 else
509 SET_ALLOC();
510
511 return CURRENT_SET();
512 }
513
514
515 struct link*
516 alloc_link
517 ()
518 { num_links++;
519 if(LDAT_FULL())
520 { if(!LCS_FULL())
521 { fprintf(stderr, "You have allocated to many (%d) links ", num_links);
522 exit(EXIT_FAILURE);
523 }
524 else
525 CSP_PUSH(lcs);
526 }
527 else
528 LDAT_ALLOC();
529
530 return CURRENT_LINK();
531
532 }
533
534 struct ref*
535 alloc_ref
536 ()
537 { num_refs++;
538 if(REF_FULL())
539 { if(!RCS_FULL())
540 { fprintf(stderr, "You have allocated to many (%d) refs ", num_refs);
541 exit(EXIT_FAILURE);
542 }
543 else
544 CSP_PUSH(rcs);
545 }
546 else
547 REF_ALLOC();
548
549
550 if(num_refs % 16 == 0)
551 { CURRENT_POST() = CURRENT_REF();
552 inc_posts();
553 }
554
555 return CURRENT_REF();
556 }
557
558 void
559 inc_posts()
560 { num_posts++;
561 if(POST_FULL())
562 { if(!PCS_FULL())
563 { fprintf(stderr, "You have allocated to many (%d) refs ", num_posts);
564 exit(EXIT_FAILURE);
565 }
566 else
567 CSP_PUSH(pcs);
568 }
569 else
570 POST_ALLOC();
571
572 }
573
574 struct cdat*
575 curr_cdat
576 ()
577 {
578 return (*cdat_stackp);
579 }
580
581 struct odat*
582 curr_odat
583 ()
584 {
585 return CURRENT_ODAT();
586 }
587
588 struct vdat*
589 curr_vdat
590 ()
591 {
592 return CURRENT_VDAT();
593 }
594
595 struct set*
596 curr_cdat_set
597 ()
598 {
599 return CURRENT_SET();
600 }
601
602 struct set*
603 curr_set
604 (int depth)
605 { int i;
606 struct set* setp;
607
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");
611 return NULL;
612 }
613 }
614
615
616 return setp;
617 }
618
619 struct ref*
620 curr_ref
621 ()
622 {
623 return CURRENT_REF();
624 }
625 struct ref*
626 prev_ref
627 ()
628 {
629 return PREVIOUS_REF();
630 }
631 struct model*
632 curr_model
633 ()
634 {
635 return &CURRENT_MODEL();
636 }
637
638 /* IR.C*/
639 void
640 push_cdat
641 ( name )
642 struct name* name;
643 {
644 struct cdat* curr_cdatp;
645
646 curr_cdatp = alloc_cdat();
647
648 name_u8_cpy(&curr_cdatp->name, name);
649 curr_cdatp->idx = num_cdats;
650
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;
655
656 }
657
658 void
659 pop_cdat
660 ()
661 {
662 cdat_stackp--;
663 }
664
665
666 void
667 insert_set_name
668 ( name )
669 struct name* name;
670 {
671 //Push name onto current namelist, set the set_namelist.
672 name_u8_cpy(&set_namelist[set_numnames++], name);
673
674
675 }
676
677
678 void
679 insert_set_namelist
680 ( name )
681 struct name* name;
682 { int depth, nameidx, i;
683
684 insert_set_name(name);
685
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
690
691
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]);
701
702 /* Alloc set and odat */
703 ss.set_frames[depth].odatp = alloc_odat();
704 ss.set_frames[depth].setp = alloc_set();
705
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;
709
710 /* Insert allocated set and odat into their respective trees if there is a depth
711 (they have parents) */
712 if(depth)
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;
716 else
717 { printf("you have allocated too many sets in insert_namelist()\n");
718 //TODO: EXIT()
719 }
720 }
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;
725 else
726 { printf("you have allocated too many sets in insert_namelist()\n");
727 //TODO: EXIT()
728 }
729 }
730
731
732 ss.set_frames[depth].num_names = set_numnames;
733 ss.curr_depth = depth;
734 }
735
736 }
737
738 }
739 done:
740 ;
741 }
742
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)
750 void
751 insert_map
752 ( name, direction, height, width, refid, filepath )
753 struct name* name;
754 int direction, height, width, refid;
755 uint8_t* filepath;
756 { int i;
757 struct odat* curr_mem_odatp; //pointer to odat in odat_buf
758 struct set* curr_mem_setp; //pointer to set in set_buf
759 struct link* linkp;
760
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.
767
768 //insert parent 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;
773 else
774 { printf("You have allocated to many sets, error in insert_map()\n");
775 //TODO: EXIT()
776 }
777
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);
782
783 /* set cdat idx values for both set and odat */
784 curr_mem_setp->cdat_idx = num_cdats;
785
786
787 /* Generate refid if needed, put into ref_buf */
788 if(!refid)
789 refid = ss_refid++;
790
791 insert_ref(curr_mem_odatp, refid);
792
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)
795 { //alloc a link
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;
801
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]);
807 }
808 else
809 curr_mem_odatp->vdat_idx = CURR_SS_ODATP()->vdat_idx;
810
811
812
813
814 }
815
816
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
820
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 */
823 void
824 insert_framesheet
825 ( model_name, direction, height, width, refid, filepath )
826 struct name* model_name;
827 int direction, height, width, refid;
828 uint8_t* filepath;
829 { struct vdat* curr_vdatp;
830 struct model* curr_modelp;
831 static struct name last_model_name[32];
832
833
834 curr_vdatp = curr_vdat();
835
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
843 }
844
845
846 if(CURR_SS_ODATP()->refid == 0)
847 { if(!refid)
848 refid = ss_refid++;
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.
851 }
852 else
853 printf("error: redefining a previously set refid\n");
854
855 curr_modelp = curr_model();
856
857 name_u8_cpy(&curr_modelp->name, model_name);
858 curr_modelp->spritesheet[direction].height = height;
859 curr_modelp->spritesheet[direction].width = width;
860
861 name_u8_cpy(last_model_name, model_name);
862
863
864 }
865
866
867
868 //src_path is stored in link_namelist
869 void
870 insert_mlink
871 ( src_mapname, src_refid)
872 struct name* src_mapname;
873 int src_refid;
874 { struct link* linkp;
875 int i;
876
877 linkp = alloc_link();
878
879 /* set type */
880 linkp->type = 3;
881 /* set the name of the src map for the link, if a name exists */
882 if(src_mapname)
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);
890 }
891 link_numnames = 0;
892
893 linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack
894
895 }
896
897 void
898 insert_link_name
899 ( name )
900 struct name* name;
901 {
902 //Push name onto current namelist, set the set_namelist.
903 name_u8_cpy(&link_namelist[link_numnames++], name);
904
905 }
906
907 /* Nearly identical to mlink */
908 void
909 insert_vlink
910 ( src_animname, src_refid )
911 struct name* src_animname;
912 int src_refid;
913 { struct link* linkp;
914 int i;
915
916 linkp = alloc_link();
917
918 /* set type */
919 linkp->type = 2;
920
921 /* set the name of the src animname for the link, if a name exists */
922 if(src_animname)
923 name_u8_cpy(&linkp->link_t.vlink.src_animname, src_animname);
924
925 /* Set the source ref id of the link */
926 linkp->link_t.mlink.src_refid = src_refid;
927
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
932 }
933
934 linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack
935
936 }
937
938
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. */
941 void
942 insert_ref
943 ( odatp, refid )
944 struct odat* odatp;
945 int refid;
946 { struct ref* curr_refp;
947 struct ref* prev_refp;
948
949 curr_refp = alloc_ref();
950 prev_refp = prev_ref();
951
952 prev_refp->nextref = curr_refp;
953 curr_refp->lastref = prev_refp;
954
955 curr_refp->odatp = odatp;
956 curr_refp->refid = refid;
957
958 if(refid % 16)
959 { POST_ALLOC();
960 CURRENT_POST()->refid = refid;
961 CURRENT_POST()->odatp = odatp;
962 }
963
964
965
966 }
967
968 void
969 insert_vdat
970 ()
971 { struct odat* curr_ss_odatp;
972 struct vdat* curr_vdatp;
973
974 curr_vdatp->creator = curr_ss_odatp;
975 curr_ss_odatp->vdat_idx = num_vdats;
976 curr_ss_odatp->vdatp = curr_vdatp;
977 alloc_vdat();
978 }
979
980 void
981 insert_refid_statement
982 ( refid )
983 int refid;
984 { CURR_SS_ODATP()->refid = refid;
985 }
986 #if 0
987
988
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*/
999
1000 //TODO: Add insert_set_ref()
1001 //TODO: Is this the correct allocation scheme? No do the one ken suggested
1002 void
1003 insert_s_name
1004 ( struct name* name
1005 )
1006 {
1007
1008 struct set* curr_setp;
1009
1010 curr_setp = curr_set();
1011 curr_set_odatp = alloc_odat();
1012
1013 u8_cpy(curr_set_odatp->name, name, 32);
1014 u8_cpy(curr_setp->name, name, 32);
1015 curr_set_odatp->parent_odatp = NULL;
1016
1017
1018 }
1019
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*/
1022 void
1023 insert_set_olink
1024 ( int refid
1025 )
1026 {
1027 struct set* curr_setp;
1028
1029 curr_setp = curr_set();
1030
1031 curr_setp->refid = refid;
1032
1033 }
1034
1035 void
1036 insert_set_vlink
1037 ( int refid,
1038 uint8_t* anim_name
1039 )
1040 {
1041 struct cdat* curr_cdatp;
1042 struct odat* curr_odatp;
1043 struct link* curr_linkp;
1044
1045
1046 curr_cdatp = curr_cdat();
1047 curr_odatp = curr_odat();
1048 curr_linkp = alloc_link();
1049
1050 /* Insert vlink into link_stack so that it gets processed at
1051 output time */
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;
1061
1062 }
1063
1064 /* Svlinks dont have animation names */
1065 void
1066 insert_set_svlink
1067 ( int refid
1068 )
1069 {
1070 struct cdat* curr_cdatp;
1071 struct link* curr_linkp;
1072
1073 curr_cdatp = curr_cdat();
1074 curr_linkp = alloc_link();
1075
1076 /* Insert svlink into link_stack so that it gets processed at
1077 output time */
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;
1083
1084 }
1085
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). */
1090 void
1091 insert_set
1092 ()
1093 { int refid;
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;
1100
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();
1107
1108 curr_vdatp->creator = curr_set_odatp;
1109
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++;
1113
1114 curr_odatp->cdat_idx = curr_cdatp->idx;
1115 curr_odatp->refp = curr_refp;
1116
1117 refid = curr_setp->refid; // refid set by insert_set_label(name, refid)
1118
1119 curr_refp->refid = refid;
1120 curr_refp->lastref = prev_refp;
1121 curr_refp->odatp = curr_odatp;
1122 prev_refp->nextref = curr_refp;
1123
1124
1125
1126 }
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). */
1130 void
1131 insert_set_vdatid
1132 ()
1133 {
1134 struct vdat* curr_vdatp;
1135
1136 curr_vdatp = curr_vdat();
1137
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
1141 }
1142
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(). */
1145 void
1146 insert_ele_label
1147 ( uint8_t* name,
1148 int refid
1149 )
1150 {
1151 struct odat* curr_odatp;
1152
1153 curr_odatp = alloc_odat();
1154
1155 u8_cpy(curr_odatp->name, name, 32);
1156 curr_odatp->map[0] = 0;
1157
1158 if(refid != -1)
1159 curr_odatp->refid = refid;
1160 else
1161 curr_odatp->refid = ss_refid++;
1162
1163 }
1164
1165 /* We don't make an odat here, at output time we will resolve
1166 the refid to the corresponding odat. */
1167 void
1168 insert_ele_olink
1169 ( int refid
1170 )
1171 {
1172 /* Do nothing because we already know the refid that
1173 the odat needs for this element (in the quad_file) */
1174 }
1175
1176 void
1177 insert_ele_vlink
1178 ( int refid,
1179 uint8_t* anim_name
1180 )
1181 {
1182 struct cdat* curr_cdatp;
1183 struct set* curr_setp;
1184 struct link* curr_linkp;
1185
1186 curr_cdatp = curr_cdat();
1187 curr_setp = curr_set();
1188 curr_linkp = alloc_link();
1189
1190 /* Insert vlink into link_stack so that it gets processed at
1191 output time */
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);
1198
1199 }
1200
1201 void
1202 insert_ele_svlink
1203 ( int refid
1204 )
1205 {
1206 struct cdat* curr_cdatp;
1207 struct set* curr_setp;
1208 struct link* curr_linkp;
1209
1210 curr_cdatp = curr_cdat();
1211 curr_setp = curr_set();
1212 curr_linkp = alloc_link();
1213
1214 curr_linkp->classp = curr_cdatp;
1215 curr_linkp->type = 3;
1216
1217 //curr_linkp->ele_idx = curr_setp->num_ele;
1218 curr_linkp->link_t.svlink.refid = refid;
1219
1220
1221 }
1222
1223 //Insert element into odat_buf and cdatpages
1224 void
1225 insert_ele()
1226 {
1227 int refid;
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;
1235
1236
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();
1242
1243 curr_vdatp->creator = curr_odatp;
1244
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;
1249
1250 refid = curr_odatp->refid;
1251
1252 curr_refp->refid = refid;
1253 curr_refp->lastref = prev_refp;
1254 curr_refp->odatp = curr_odatp;
1255 prev_refp->nextref = curr_refp;
1256
1257 }
1258
1259 void
1260 insert_ele_vdatid
1261 ()
1262 { struct odat* curr_odatp;
1263 curr_odatp = curr_odat();
1264 curr_odatp->vdat_id = num_vdats;
1265 }
1266
1267
1268
1269 #endif
1270
1271
1272
1273
1274 /* void */
1275 /* insert_quad */
1276 /* ( int x, int y, int z, int refid */
1277 /* ) */
1278 /* { */
1279 /* struct quad* curr_quadp; */
1280
1281 /* curr_quadp = curr_quad(); */
1282
1283 /* curr_quadp->x = x; */
1284 /* curr_quadp->y = y; */
1285 /* curr_quadp->z = z; */
1286 /* curr_quadp->refid = refid; */
1287
1288
1289
1290 /* } */
1291
1292 /* /\* serting the hitbox into the set */
1293 /* odat. Elements that don't have */
1294 /* a hitbox will use the sets root. *\/ */
1295 /* void */
1296 /* insert_hitbox */
1297 /* ( int hitbox */
1298 /* ) */
1299 /* { struct odat* curr_odatp; */
1300
1301 /* curr_odatp = curr_odat(); */
1302 /* curr_odatp->hitbox = hitbox; */
1303 /* } */
1304
1305 /* /\* Inserting the root into the set */
1306 /* odat. Elements that don't have */
1307 /* a root will use the sets root. *\/ */
1308 /* void */
1309 /* insert_root */
1310 /* ( int x, */
1311 /* int y, */
1312 /* int z */
1313 /* ) */
1314 /* { struct odat* curr_odatp; */
1315
1316 /* curr_odatp = curr_odat(); */
1317 /* curr_odatp->root.x = x; */
1318 /* curr_odatp->root.y = y; */
1319 /* curr_odatp->root.z = z; */
1320 /* } */
1321
1322
1323
1324
1325 /* void */
1326 /* insert_frame_pointer */
1327 /* ( uint8_t direction, */
1328 /* void* frame */
1329 /* ) */
1330 /* { struct model* curr_modelp; */
1331
1332 /* curr_modelp = curr_model(); */
1333
1334 /* curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */
1335 /* } */
1336