/*!@file \brief Intermediate Representation (IR) between Directory Structure and Engine Grammar \details The IR serves as a storage structure that is populated during the parsing of the input directory structure. After parsing is complete, the IR will be condensed (removed of excess allocated space) and then output as the Engine Grammar. In this file we describe the semantic actions that are called at each step, and the memory buffers that they populate. See parser.y for the description on how the input grammar is constructed, and where/when semantic actions are called. TODO: or just write it here. \author Jordan Lavatai \date Aug 2016 ----------------------------------------------------------------------------*/ #include #include #include #define BUF_SIZE 256 #define MAX_SETS 256 #define MAX_ELES 256 #define MAX_QUADS 256 #define MAX_MODELS 256 #define MAX_VARIANTS 8 #define MAX_POSTS 256 #define MAX_CLASS_DEPTH 256 #define MAX_CLASSES 256 #define MAX_FRAMES 256 #define PTRS_IN_PAGE 1024 #define MAX_CHUNKS 256 #define PAGES_PER_CHUNK 16 /* Sets: elements. The set is populated at parse time AFTER the elements are populated, due to the nature of bottom up parsing. */ struct set { uint8_t name[32]; int ref_id; int cdat_idx; }; /* Cdats: A cdat is a class data structure. Cdats serve as the central */ /* data types of the IR. For each cdat, sets and element */ /* ref_ids must be dereferenced to determine the odat information. Cdats */ /* contain pointers to their subclasses so that the relationship between */ /* classes can be determined, but the subclasses are not represented inside */ /* of the cdat itself but rather in subsequent cdats in cdat_buf. We */ /* can determine the number of subclasses (the last index into cdat_buf */ /* that represents a subclass of some arbitrary cdat) each cdat has by */ /* incrementing num_classes during parse time. */ /* TODO: Should classes point to their parent class? */ struct cdat { uint8_t name[32]; int idx; int num_classes; int num_sets; struct cdat* class_list[MAX_CLASSES]; struct set set_list[MAX_SETS]; }; /* The cdat_stack is a stack pointers to cdat pointers, the top of which is the cdat that is currently being parsed. Whenever a new cdat is recognized by the grammar (CLOPEN), a cdat is pushed onto the cdat_stack, and we refer to this cdat through the macro CURR_CDAT. By keeping a cdat_stack, we have access to the current cdat so that the elements and sets can populate themselves in the cdat accordingly. */ /* Refs: Each set/ele has a reference to its object data (odat) through a ref_id. Ref_ids are unsigned 64 byte integers that map to the hex values RGBA. During the construction of the directory structure, users can choose a RGBA value for each object that any other object can refer to via links (see link). If a user does not choose an RGBA value, then the object is given one from the system space. We maintain a doubly linked list of refs in the ref_buf at parse time so that links can be resolved after the parsing of the directory structure is complete. For every 16th ref, we create a post so that we can reduce on the search time for a random access. */ struct ref { int type; struct ref* nextref; struct ref* lastref; struct odat* odatp; int ref_id; //0xFFFFFF->digit }; /* Links: At parse time, a set/ele can include a link in their grammar representation instead of the actual data and this signifies to the APC that that set/ele wishes to use the data of another set/ele, either its video data (vdat) or object data (odat). The link itself contains the type of link it is, the ref_id OR name, and which set/ele created the link. During parse time, links can be made to o/vdats that have yet to be parsed. In order to accomodate for this, we resolve all links AFTER parse time by iterating through the link_buf, finding the ref_id that was stored for some object (if the ref_id exists), and creating a relative pointer from the original object to the data that was linked */ /* Svlinks stand for short vlink, which is a link to a vdat. svlinks differ from vlinks because they do not have a name */ struct svlink { int ref_id; }; /* A vlink is what it sounds like, a link to a vdat */ struct vlink { int ref_id; uint8_t anim_name[32]; }; union link_t { struct vlink vlink; struct svlink svlink; }; /* From: src odat ()To: dest odat (ref_id)*/ struct link { int type; //1 = olink, 2 = vlink, 3 = svlink union link_t link_t; struct cdat* classp; struct odat* odatp; int set_idx; int ele_idx; }; struct root { int x, y, z; }; struct quad { int x; int y; int z; int ref_id; }; /* variants: variants store the different map data for each archetype. */ struct variant { uint8_t filename[NAME_MAX/sizeof(ucs4_t)]; uint8_t filepath[PATH_MAX/sizeof(ucs4_t)]; int height; int width; // int num_quads; //struct quad quad_list[MAX_QUADS]; }; /* Odats: Odats consist of the object data necessary for each object. Odats are sometimes referred to as archetypes at compile-time, in order to distinguish the difference from a runtime object and a compile-time object. TODO: Need more info about objects at runtime, to described the reasoning behind odat structure at compile-time*/ struct odat { uint8_t name[32]; struct vdat* vdatp; int vdat_id; // int cdat_idx; int hitbox; int ref_id; struct odat* parent_odatp; // odat == set ? null : set ref_id struct root root; struct ref* refp; /* pointer to it's ref on ref_list */ struct variant* variant_list[MAX_VARIANTS]; int vli; //variant list index }; struct odat* curr_set_odatp; //when a set has elements, insert_set() can no longer //refer to its odat via curr_odat, so save the set odat. /* A framesheet is a grouping of animation frames in a single direction (N,W,S,E) */ struct framesheet { int width; int height; int num_frames; void* frames[MAX_FRAMES]; }; /* A model is a collection of framesheets for every direction (N,W,S,E,NW,NE,SW,SE)*/ /* NAMED spritesheet */ struct model { uint8_t name[32]; struct framesheet spritesheet[8]; //one for each }; /* Vdat: Vdats are the video data of each object. They can not be created as a stand alone object (because they consist solely of animation information and not the skeleton which the animation manipulates). Vdats have a list of models for every animation that the vdats odat can do for that vdat*/ struct vdat { struct odat* creator; //pointer to odat that made this vdat int num_models; uint8_t filename[NAME_MAX/sizeof(ucs4_t)]; int height; int width; uint8_t filepath[PATH_MAX/sizeof(ucs4_t)]; //struct model model_list[MAX_MODELS]; }; /* Called after the cdat open operator has been recognized in grammar. Allocates the space for a cdat on the cdat_buf, pushes that pointer onto the cdat_stack */ void push_cdat(uint8_t*); /* Called after a cdat end operator has been recognized in grammar. Sets top stack cdat ** to null and decrements stack pointer */ void pop_cdat(void); /* Called after an odat has been populated. Allocates memory for the next odat. */ void insert_set_label(uint8_t*, int); /* Populate the sets representation in CURR_CDAT with a ref_id and insert a link into the link_buf that will resolve the ref_id to an actual odat after parse time. */ void insert_set_olink(int); /* Put the vlink in the link_buf to be processed after parsetime */ void insert_set_vlink(int, uint8_t*); /* Put svlink in the link_buf to be processed after parsetime */ void insert_set_svlink(int); /* Called for every set reduction except for sets with olinks. Populates the set data structures in the CDAT and in the ODAT. Uses the name and ref_id from insert_set_label. Also inserts a ref into the ref_buf with the CURR_ODAT pointer so that we can also resolve the odat from its ref_id. */ void insert_set(void); /* Insertion of eles is practically equivalent to how sets are inserted because both share the same data type (ODAT). Like sets, eles have links, labels and odats. Eles have the added notion of a parent set, and so must be inserted into said parent set, but this is the only place they truly differ from sets. */ void insert_set_vdatid(void); void insert_ele_label(uint8_t*, int); /* Insert an ele olink into the CURR_ODAT */ void insert_ele_olink(int); /* Insert a ele vlink into CURR_ODAT*/ void insert_ele_vlink(int, uint8_t*); /* Inserts an ele short vlink into CURR_ODAT*/ void insert_ele_svlink(int); /* inserts ele into CURR_CLASS and CURR_ODAT */ void insert_ele(void); void insert_ele_vdatid(void); void insert_vdat(uint8_t*, int, int, uint8_t*); /* Inserts the hitbox into the CURR_ODAT */ void insert_hitbox(int); /* Inserts the root into the CURR_ODAT */ void insert_root(int, int, int); /* Inserts a quad into the CURR_ODAT */ void insert_quad(int, int, int, int); void insert_variant(uint8_t*, int, int, uint8_t*); void insert_model(void); void insert_framesheet(uint8_t, uint8_t*, int, int, int, int); void insert_frame_pointer(uint8_t, void*);