From: jordan@hack_attack Date: Fri, 30 Sep 2016 21:26:44 +0000 (-0700) Subject: api with struct definitions in header file X-Git-Url: https://git.kengrimes.com/?p=henge%2Fwebcc.git;a=commitdiff_plain;h=92d574d704e54743631464fac3ce739b1077222c api with struct definitions in header file --- diff --git a/src/apc/ir.c b/src/apc/ir.c index 1d56bd1..bf62227 100644 --- a/src/apc/ir.c +++ b/src/apc/ir.c @@ -12,49 +12,71 @@ #include + +/* functions needed from irmem.c */ +extern void ir_init(void); -void -malloc_cdat(void); +extern +struct cdat* +alloc_cdat(void); +extern +struct odat* +alloc_odat(void); -/* The initalization function of the IR. Mallocs the - first c/v/odat and the first links and refs and - inits the cdat_stack */ +extern void -ir_init() -{ +alloc_vdat(void); - /* Init root cdat and stack */ - char root[4] = "root"; +extern +struct link* +alloc_link(void); - cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof(struct cdat) ); - cdat_buf[num_cdats]->idx = 0; - memmove(cdat_buf[num_cdats]->name, root, 4); +extern +struct ref* +alloc_ref(void); - cdat_stackp = cdat_stack; - *cdat_stackp = cdat_buf[num_cdats++]; +extern +struct cdat* +curr_cdat(void); -} +extern +struct odat* +curr_odat(void); -//TODO: FREE MEMORY! -void -malloc_cdat() -{ - if(curr_max_cdats <= num_cdats) - { if( (realloc((void*) cdat_buf, PTRS_IN_PAGE * 4)) == NULL) - perror("realloc cdat_buf failed"); - curr_max_cdats += PTRS_IN_PAGE; - if( (realloc( (void*) cdat_stack, PTRS_IN_PAGE * 4)) == NULL) //increase cdat_stack also - perror("realloc cdat_stack failed"); - } - if( (cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof (struct cdat)) ) == NULL ) - perror("malloc cdat failed"); +extern +struct vdat* +curr_vdat(void); +extern +struct ele* +curr_ele(void); -} +extern +struct set* +curr_set(void); +extern +struct ref* +prev_ref(void); + +extern +struct quad* +curr_quad(void); + +extern +struct model* +curr_model(void); + +/* struct definitions needed from irmem.c */ +extern int num_cdats; +extern struct cdat** cdat_stackp; +extern struct odat* curr_set_odatp; +extern uint64_t ss_ref_id; + +extern int num_vdats; /* Dynamically allocate memory for a class data structure, or cdat, after a class has been identified in a grammar. We also create a stack of class pointers so that @@ -68,16 +90,17 @@ push_cdat ( char* name ) { - malloc_cdat(); + struct cdat* curr_cdatp; - memmove(cdat_buf[num_cdats]->name, name, 32); - cdat_buf[num_cdats]->idx = num_cdats; + curr_cdatp = alloc_cdat(); - /* Set the cdat as a class of the previous cdat */ - (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes++] = cdat_buf[num_cdats]; + memmove(curr_cdatp->name, name, 32); + curr_cdatp->idx = num_cdats; + + /* Set the cdat as a subclass of the previous cdat */ /* Push the cdat onto the cdat_stack */ - *++cdat_stackp = cdat_buf[num_cdats++]; + *++cdat_stackp = curr_cdatp; } @@ -92,14 +115,12 @@ pop_cdat /* Called in the reduction of a set. While both odats (eles and sets) have identical label terminals, we are unable to give a single grammatical rule for both due to how we allocate odats in the odat buf. Due to the - nature of bottom up parsing, all the elements will be inserted into the - odat_buf first, and then the set that contains these element is inserted. Since - the sets label comes before the element list in the grammar, we would be giving an element - a set label in its respective odat, which would then be replaced by the - elements label. Instead, we store the label in the sets representation inside - CURR_CDAT and after we are done parsing the element_list and know that the CURR_ODAT - is the set, we populate the sets label members in CURR_ODAT with the values we stored - previously in CURR_CDAT. */ + nature of bottom up parsing, the set label is recognized first, and then the + sets elements are recognized. This means that after we have processed the sets elemenets, + the curr_odat is going to be the last element and NOT the set that was first allocated. + To get around this, we create a global variable set_odatp that will store the pointer + to the odat when it is first allocated (in insert_set_label()) so that insert_set() can + have access to it. */ void insert_set_label @@ -107,11 +128,14 @@ insert_set_label uint64_t ref_id ) { - struct set* curr_set; + struct set* curr_setp; + + curr_setp = curr_set(); + curr_set_odatp = alloc_odat(); - curr_set = curr_set(); - memmove(curr_set.name,name,32); - curr_set.ref_id = ref_id; + memmove(curr_set_odatp->name, name, 32); + memmove(curr_setp->name, name, 32); + curr_setp->ref_id = ref_id; } void @@ -119,22 +143,22 @@ insert_set_olink ( uint64_t ref_id ) { - struct set* curr_set; - struct cdat* curr_cdat; - struct link* curr_link; + struct set* curr_setp; + struct cdat* curr_cdatp; + struct link* curr_linkp; - curr_set = curr_set(); - curr_cdat = curr_cdat(); - curr_link = alloc_link(); + curr_setp = curr_set(); + curr_cdatp = curr_cdat(); + curr_linkp = alloc_link(); - curr_set.cdat_idx = curr_cdat->idx; - curr_set.ref_id = ref_id; /* Will be resolved to offset + curr_setp->cdat_idx = curr_cdatp->idx; + curr_setp->ref_id = ref_id; /* Will be resolved to offset when link is processed */ - curr_link->type = 1; - curr_link->link_t.olink.ref_id = ref_id; - curr_link->cdat_idx = curr_cdat->idx; - curr_link->set_idx = curr_cdat->num_sets++; - curr_link->ele_idx = -1; + curr_linkp->type = 1; + curr_linkp->link_t.olink.ref_id = ref_id; + curr_linkp->cdat_idx = curr_cdatp->idx; + curr_linkp->set_idx = curr_cdatp->num_sets++; + curr_linkp->ele_idx = -1; } @@ -144,19 +168,20 @@ insert_set_vlink char* anim_name ) { - struct cdat* curr_cdat; - struct link* curr_link; + struct cdat* curr_cdatp; + struct link* curr_linkp; - curr_cdat = curr_cdat(); - curr_link = alloc_link(); + curr_cdatp = curr_cdat(); + curr_linkp = alloc_link(); /* Insert vlink into link_stack so that it gets processed at output time */ - curr_link->type = 2; - curr_link->cdat_idx = curr_cdat->idx; - curr_link->set_idx = curr_cdat->num_sets; - curr_link->link_t.vlink.ref_id = ref_id; - memmove(curr_link->link_t.vlink.anim_name, anim_name, 32); + curr_linkp->type = 2; + curr_linkp->link_t.vlink.ref_id = ref_id; + curr_linkp->cdat_idx = curr_cdatp->idx; + curr_linkp->set_idx = curr_cdatp->num_sets; + curr_linkp->ele_idx = -1; + memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32); } @@ -166,18 +191,18 @@ insert_set_svlink ( uint64_t ref_id ) { - struct cdat* curr_cdat; - struct link* curr_link; + struct cdat* curr_cdatp; + struct link* curr_linkp; - curr_cdat = curr_cdat(); - curr_link = alloc_link(); + curr_cdatp = curr_cdat(); + curr_linkp = alloc_link(); /* Insert vlink into link_stack so that it gets processed at output time */ - curr_link->type = 3; - curr_link->cdat_idx = curr_cdat->idx; - curr_link->set_idx = curr_cdat->num_sets; - curr_link->link_t.svlink.ref_id = ref_id; + curr_linkp->type = 3; + curr_linkp->cdat_idx = curr_cdatp->idx; + curr_linkp->set_idx = curr_cdatp->num_sets; + curr_linkp->link_t.svlink.ref_id = ref_id; } @@ -188,68 +213,71 @@ insert_set_svlink void insert_set () -{ - struct odat* curr_odat; - struct cdat* curr_cdat; - struct ref* prev_ref; - struct ref* curr_ref; - - curr_odat = alloc_odat(); - curr_cdat = curr_cdat(); - curr_set = curr_set(); - prev_ref = prev_ref(); - curr_ref = alloc_ref(); +{ uint64_t ref_id; + struct odat* curr_odatp; + struct cdat* curr_cdatp; + struct set* curr_setp; + struct ref* prev_refp; + struct ref* curr_refp; - ref_id = curr_set.ref_id; // ref_id set by insert_set_label(name, ref_id) + curr_odatp = curr_set_odatp; //allocated at insert_set_label, preserved in global space + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + prev_refp = prev_ref(); + curr_refp = alloc_ref(); - curr_set.cdat_idx = curr_cdat->idx; - memmove(curr_odat->name, curr_set.name, 32); - curr_cdat.num_sets++; - curr_odat->cdat_idx = curr_cdaat->idx; - curr_odat->refp = curr_ref; + curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx? + memmove(curr_setp->name, curr_odatp->name, 32); + curr_cdatp->num_sets++; + curr_odatp->cdat_idx = curr_cdatp->idx; + curr_odatp->refp = curr_refp; - curr_ref->lastref = prev_ref; - prev_ref->nextref = curr_ref; - curr_ref->odatp = curr_odat; + ref_id = curr_setp->ref_id; // ref_id set by insert_set_label(name, ref_id) - - if(ref_id == -1) /* user did not define a ref_id so */ + if(ref_id == -1) /* user did not define a ref_id */ { ref_id = ss_ref_id; ss_ref_id++; } - curr_ref->ref_id = ref_id; + curr_refp->ref_id = ref_id; + curr_refp->lastref = prev_refp; + curr_refp->odatp = curr_odatp; + prev_refp->nextref = curr_refp; + + } /* Created as a seperate function, instead of setting the ODATS vdat_id and calling inc_vdat() inside of insert_set(), to account for the set reduction where a vdat is not created (o/v/svlinks). */ - void -insert_vdat_id +insert_set_vdatid () { - struct odat* curr_odat; - curr_odat = curr_odat(); - curr_odat->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks + curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks + curr_set_odatp = NULL; //So this sets odat cant be modified after (which would be a bug) } /* Populates both the odat name and ref_id - for element. */ + for odat and ele */ void insert_ele_label ( char* name, uint64_t ref_id ) { - struct ele* curr_ele; + struct ele* curr_elep; + struct odat* curr_odatp; + + curr_elep = curr_ele(); + curr_odatp = alloc_odat(); - curr_ele = curr_ele(); + memmove(curr_odatp->name, name, 32); - memmove(curr_ele.name, name, 32); - curr_ele.ref_id = ref_id; + memmove(curr_elep->name, name, 32); + curr_elep->ref_id = ref_id; } void @@ -257,14 +285,23 @@ insert_ele_olink ( uint64_t ref_id ) { - CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx; - CURR_CDAT->CURR_SET.CURR_ELE.ref_id = ref_id; /* Will be resolved to offset + struct cdat* curr_cdatp; + struct set* curr_setp; + struct ele* curr_elep; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_elep = curr_ele(); + curr_linkp = alloc_link(); + + curr_elep->cdat_idx = curr_cdatp->idx; + curr_elep->ref_id = ref_id; /* Will be resolved to offset when link is processed */ - CURR_LINK->type = 1; - CURR_LINK->link_t.olink.ref_id = ref_id; - CURR_LINK->cdat_idx = CURR_CDAT->idx; - CURR_LINK->set_idx = CURR_CDAT->num_sets++; - CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele++; + curr_linkp->type = 1; + curr_linkp->link_t.olink.ref_id = ref_id; + curr_linkp->cdat_idx = curr_cdatp->idx; + curr_linkp->set_idx = curr_cdatp->num_sets++; + curr_linkp->ele_idx = curr_setp->num_ele++; } @@ -274,15 +311,22 @@ insert_ele_vlink char* anim_name ) { + struct cdat* curr_cdatp; + struct set* curr_setp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + curr_linkp = alloc_link(); /* Insert vlink into link_stack so that it gets processed at output time */ - CURR_LINK->cdat_idx = CURR_CDAT->idx; - CURR_LINK->type = 2; - CURR_LINK->set_idx = CURR_CDAT->num_sets; - CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele; - CURR_LINK->link_t.vlink.ref_id = ref_id; - memmove(CURR_LINK->link_t.vlink.anim_name, anim_name, 32); + curr_linkp->cdat_idx = curr_cdatp->idx; + curr_linkp->type = 2; + curr_linkp->set_idx = curr_cdatp->num_sets; + curr_linkp->ele_idx = curr_setp->num_ele; + curr_linkp->link_t.vlink.ref_id = ref_id; + memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32); } @@ -291,12 +335,19 @@ insert_ele_svlink ( uint64_t ref_id ) { + struct cdat* curr_cdatp; + struct set* curr_setp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + curr_linkp = alloc_link(); - CURR_LINK->cdat_idx = CURR_CDAT->idx; - CURR_LINK->type = 3; - CURR_LINK->set_idx = CURR_CDAT->num_sets; - CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele; - CURR_LINK->link_t.svlink.ref_id = ref_id; + curr_linkp->cdat_idx = curr_cdatp->idx; + curr_linkp->type = 3; + + curr_linkp->ele_idx = curr_setp->num_ele; + curr_linkp->link_t.svlink.ref_id = ref_id; } @@ -306,42 +357,49 @@ void insert_ele() { uint64_t ref_id; - - ref_id = CURR_CDAT->CURR_SET.CURR_ELE.ref_id; - - CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx; - memmove(CURR_ODAT->name,CURR_CDAT->CURR_SET.CURR_ELE.name, 32); - CURR_CDAT->CURR_SET.num_ele++; - - CURR_ODAT->cdat_idx = CURR_CDAT->idx; - CURR_ODAT->refp = CURR_REF; + struct cdat* curr_cdatp; + struct odat* curr_odatp; + struct set* curr_setp; + struct ele* curr_elep; + struct ref* curr_refp; + struct ref* prev_refp; + + curr_cdatp = curr_cdat(); + curr_odatp = curr_odat(); //malloced @ insert_ele_label + curr_setp = curr_set(); + curr_elep = curr_ele(); + curr_refp = alloc_ref(); + prev_refp = prev_ref(); + + /* Populate ele in cdat */ + curr_elep->cdat_idx = curr_cdatp->idx; + curr_setp->num_ele++; + + /* Populate odat for ele */ + curr_odatp->cdat_idx = curr_cdatp->idx; + curr_odatp->refp = curr_refp; + + /* Add ele to ref_buf */ + ref_id = curr_elep->ref_id; if(ref_id == -1) /* user did not define a ref_id so */ { ref_id = ss_ref_id; ss_ref_id++; } - CURR_REF->ref_id = ref_id; - - inc_odat(); - inc_ref(); + curr_refp->ref_id = ref_id; + curr_refp->lastref = prev_refp; + curr_refp->odatp = curr_odatp; + prev_refp->nextref = curr_refp; } void -insert_framesheet -( char direction, - char* name, - uint64_t ref_id, - int height , - int width, - int num_frames -) -{ - CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].height = height; - CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].width = width; - CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames = num_frames; - CURR_VDAT->num_models++; +insert_ele_vdatid +() +{ struct odat* curr_odatp; + curr_odatp = curr_odat(); + curr_odatp->vdat_id = num_vdats; } void @@ -351,13 +409,19 @@ insert_quad int z, uint64_t ref_id ) -#define CURR_QUAD (CURR_ODAT->quad_list[CURR_ODAT->num_quads]) { - CURR_QUAD.x = x; - CURR_QUAD.y = y; - CURR_QUAD.z = z; - CURR_QUAD.ref_id = ref_id; - CURR_ODAT->num_quads++; + + struct quad* curr_quadp; + struct odat* curr_odatp; + + curr_quadp = curr_quad(); + curr_odatp = curr_odat(); + + curr_quadp->x = x; + curr_quadp->y = y; + curr_quadp->z = z; + curr_quadp->ref_id = ref_id; + curr_odatp->num_quads++; } /* Inserting the hitbox into the set @@ -367,8 +431,10 @@ void insert_hitbox ( int hitbox ) -{ - CURR_ODAT->hitbox = hitbox; +{ struct odat* curr_odatp; + + curr_odatp = curr_odat(); + curr_odatp->hitbox = hitbox; } /* Inserting the root into the set @@ -380,11 +446,34 @@ insert_root int y, int z ) -{ +{ struct odat* curr_odatp; + + curr_odatp = curr_odat(); + curr_odatp->root.x = x; + curr_odatp->root.y = y; + curr_odatp->root.z = z; +} + + +void +insert_framesheet +( char direction, + char* name, + uint64_t ref_id, + int height , + int width, + int num_frames +) +{ struct vdat* curr_vdatp; + struct model* curr_modelp; - CURR_ODAT->root.x = x; - CURR_ODAT->root.y = y; - CURR_ODAT->root.z = z; + curr_vdatp = curr_vdat(); + curr_modelp = curr_model(); + + curr_modelp->spritesheet[(int)direction].height = height; + curr_modelp->spritesheet[(int)direction].width = width; + curr_modelp->spritesheet[(int)direction].num_frames = num_frames; + curr_vdatp->num_models++; } void @@ -392,7 +481,10 @@ insert_frame_pointer ( char direction, void* frame ) -{ - CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].frames[CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames++] = frame; +{ struct model* curr_modelp; + + curr_modelp = curr_model(); + + curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; } diff --git a/src/apc/ir.h b/src/apc/ir.h index 0424f6f..cc0508f 100644 --- a/src/apc/ir.h +++ b/src/apc/ir.h @@ -26,6 +26,226 @@ #define MAX_FRAMES 256 #define PTRS_IN_PAGE 1024 +/* General: All information from the directory structure is stored in */ +/* five buffers that comprise the IR: cdat_buf, odat_buf, vdat_buf, ref_buf */ +/* and link_buf. Each buf corresponds to the data structure that it stores. */ +/* The storage techique for all bufs (except cdat) is the same. Each bufs member first */ +/* populates its struct and then allocates the space for the next member */ +/* and increments the buf index. This means that we have to allocate the */ +/* very first member of each buf at ir_init(), so that we don't segfault */ +/* as the first member attempts to access memory that its previous member */ +/* didn't allocate (because it doesnt exist). We access the buf members */ +/* through standard array indexing but conceal the tediousness of array */ +/* indexing with macros. E.g. without macros, acessing an elements name */ +/* member would look like (split up to not go over line char limit): */ +/* (*cdat_stackp)->set_list[(*cdat_stackp)->num_sets] */ +/* .ele_list[(*cdat_stackp)->set_list[(*cdat_stackp->num_sets)].num_ele].name */ + +/* For cdats in cdat_buf, we allocate the memory for a cdat once a cdat + is recognized in the grammar. Cdat_buf is different from the other bufs + because cdats have a root cdat that all cdats are a subclass of. This root + cdat can have a set_list like other cdats. */ + +/* Elements: Ele stands for element and has two representations in the IR. */ +/* In the cdat_buf eles store their name, cdat_idx (their classes index in */ +/* the cdat_buf) and the ref_id (refer to ref ). In the odat_buf, eles store */ +/* their object data (odat). At output time, the ref_id is dereferenced to */ +/* determine the elements odat which is the data that the engine expects */ +extern struct cdat** cdat_stackp; +/* from an element. */ + + +/* All bufs are of pointers to their respective structs. When a buf is full */ +/* (number of data structs pointers >= max number of data struct pointers), */ +/* we need to allocate a more pointers for that buf. Allocate these */ +/* pointers a page at a time (1024 = Page bytes (4096)/bytes per pointer(4)) */ + +struct ele { + char name[32]; + uint64_t ref_id; + int cdat_idx; +}; + +/* Sets: The set is similar to the ele, but it contains a list of its */ +/* elements. The set is populated at parse time AFTER the elements are */ +/* populated, due to the nature of bottom up parsing. */ + +struct set { + char name[32]; + uint64_t ref_id; + int cdat_idx; + int num_ele; + struct ele ele_list[MAX_ELES]; +}; + +/* Cdats: A cdat is a class data structure. Cdats serve as the central */ +/* data types of the IR. At output, the cdat_buf is iterated through and */ +/* each is written to the output file. 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 the 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 { + char name[32]; + int idx; + int num_classes; + int num_sets; + struct cdat* class_list[MAX_CLASSES]; + struct set set_list[MAX_SETS]; +}; + +/* There are an unknown amount of cdats at compile time, so we maintain */ +/* a cdat_buf of cdat pointers that can be expanded as needed. */ + +/* 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; + uint64_t ref_id; //0xFFFFFF->digit +}; + + +/* Like the cdat_buf, ref_buf stores pointers to refs and can + increase in size */ + +/* posts for ref_buf */ + +/* 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 + TODO: diff btwn vlink*/ + +struct svlink { + uint64_t ref_id; +}; + +/* A vlink is what it sounds like, a link to a vdat + TODO: model link? */ +struct vlink { + uint64_t ref_id; + char anim_name[32]; +}; + +/* Olinks are links to odats */ +struct olink { + uint64_t ref_id; +}; + +union link_t { + struct olink olink; + struct vlink vlink; + struct svlink svlink; +}; + +struct link { + int type; //1 = olink, 2 = vlink, 3 = svlink + union link_t link_t; + int cdat_idx; + int set_idx; + int ele_idx; +}; + +/* link_buf contains all the links that + we encountered during parse time that need + to be resolved to an offset at output time. + This does not include quad refs, because + those are already known to need to be resolved */ + + +/* 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*/ + +/* Each set has a quad_list or a list of quads. The quad_list + is the ? */ +struct quad { + int x, y, z; + uint64_t ref_id; //rgba +}; + +struct root { + int x, y, z; +}; + +struct odat { + char name[32]; + int vdat_id; + int cdat_idx; + int hitbox; + struct root root; + struct ref* refp; /* pointer to it's ref on ref_list */ + int num_quads; + struct quad quad_list[MAX_QUADS]; +}; + +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 { + char 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 on 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; + 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 */ @@ -68,6 +288,9 @@ insert_set(void); 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(char*, uint64_t); @@ -88,7 +311,7 @@ void insert_ele(void); void -insert_vdat(void); +insert_ele_vdatid(void); /* Inserts the hitbox into the CURR_ODAT */ void @@ -111,3 +334,5 @@ insert_framesheet(char, char*, uint64_t, int, int, int); void insert_frame_pointer(char, void*); +void +alloc_vdat(void); diff --git a/src/apc/irmem.c b/src/apc/irmem.c index 3632ea2..28234d8 100644 --- a/src/apc/irmem.c +++ b/src/apc/irmem.c @@ -5,13 +5,15 @@ #include #include #include +#include - +struct cdat* +alloc_cdat(void); struct odat* alloc_odat(void); void alloc_vdat(void); -struct ref* +struct link* alloc_link(void); struct ref* alloc_ref(void); @@ -19,12 +21,20 @@ struct cdat* curr_cdat(void); struct odat* curr_odat(void); +struct vdat* +curr_vdat(void); struct ele* curr_ele(void); struct set* curr_set(void); struct ref* prev_ref(void); +struct quad +curr_quad(void); +struct model +curr_model(void); +void +inc_posts(void); #define CURR_CDAT (*cdat_stackp) #define CURR_SET set_list[CURR_CDAT->num_sets] @@ -35,248 +45,80 @@ prev_ref(void); #define CURR_ODAT (odat_buf[num_odats]) #define CURR_VDAT (vdat_buf[num_vdats]) #define PREV_VDAT (vdat_buf[num_vdats-1]) -#define CURR_MODEL model_list[CURR_VDAT->num_models] +#define CURR_MODEL (CURR_VDAT->model_list[CURR_VDAT->num_models]) #define CURR_LINK (link_buf[num_links]) #define CURR_POST (post_buf[num_posts]) +#define CURR_QUAD (CURR_ODAT->quad_list[CURR_ODAT->num_quads]) -/* General: All information from the directory structure is stored in */ -/* five buffers that comprise the IR: cdat_buf, odat_buf, vdat_buf, ref_buf */ -/* and link_buf. Each buf corresponds to the data structure that it stores. */ -/* The storage techique for all bufs (except cdat) is the same. Each bufs member first */ -/* populates its struct and then allocates the space for the next member */ -/* and increments the buf index. This means that we have to allocate the */ -/* very first member of each buf at ir_init(), so that we don't segfault */ -/* as the first member attempts to access memory that its previous member */ -/* didn't allocate (because it doesnt exist). We access the buf members */ -/* through standard array indexing but conceal the tediousness of array */ -/* indexing with macros. E.g. without macros, acessing an elements name */ -/* member would look like (split up to not go over line char limit): */ -/* (*cdat_stackp)->set_list[(*cdat_stackp)->num_sets] */ -/* .ele_list[(*cdat_stackp)->set_list[(*cdat_stackp->num_sets)].num_ele].name */ - -/* For cdats in cdat_buf, we allocate the memory for a cdat once a cdat - is recognized in the grammar. Cdat_buf is different from the other bufs - because cdats have a root cdat that all cdats are a subclass of. This root - cdat can have a set_list like other cdats. */ - -/* Elements: Ele stands for element and has two representations in the IR. */ -/* In the cdat_buf eles store their name, cdat_idx (their classes index in */ -/* the cdat_buf) and the ref_id (refer to ref ). In the odat_buf, eles store */ -/* their object data (odat). At output time, the ref_id is dereferenced to */ -/* determine the elements odat which is the data that the engine expects */ -/* from an element. */ - - -/* All bufs are of pointers to their respective structs. When a buf is full */ -/* (number of data structs pointers >= max number of data struct pointers), */ -/* we need to allocate a more pointers for that buf. Allocate these */ -/* pointers a page at a time (1024 = Page bytes (4096)/bytes per pointer(4)) */ - -struct ele { - char name[32]; - uint64_t ref_id; - int cdat_idx; -}; - -/* Sets: The set is similar to the ele, but it contains a list of its */ -/* elements. The set is populated at parse time AFTER the elements are */ -/* populated, due to the nature of bottom up parsing. */ - -struct set { - char name[32]; - uint64_t ref_id; - int cdat_idx; - int num_ele; - struct ele ele_list[MAX_ELES]; -}; - -/* Cdats: A cdat is a class data structure. Cdats serve as the central */ -/* data types of the IR. At output, the cdat_buf is iterated through and */ -/* each is written to the output file. 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 the 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 { - char name[32]; - int idx; - int num_classes; - int num_sets; - struct cdat* class_list[MAX_CLASSES]; - struct set set_list[MAX_SETS]; -}; - -/* There are an unknown amount of cdats at compile time, so we maintain */ -/* a cdat_buf of cdat pointers that can be expanded as needed. */ -struct cdat* cdat_buf[PTRS_IN_PAGE]; -/* 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. */ +int num_cdats = -1; +int curr_max_cdats = PTRS_IN_PAGE; +struct cdat* cdat_buf[PTRS_IN_PAGE]; struct cdat* cdat_stack[PTRS_IN_PAGE]; struct cdat** cdat_stackp; -int num_cdats = 0; -int curr_max_cdats = PTRS_IN_PAGE; -/* 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; - uint64_t ref_id; //0xFFFFFF->digit -}; - - -/* Like the cdat_buf, ref_buf stores pointers to refs and can - increase in size */ -struct ref* ref_buf[PTRS_IN_PAGE]; -int num_refs = 0; + +int num_odats = -1; +int curr_max_odats = PTRS_IN_PAGE; +struct odat* odat_buf[PTRS_IN_PAGE]; + + +int num_vdats = -1; +int curr_max_vdats = PTRS_IN_PAGE; +struct vdat* vdat_buf[PTRS_IN_PAGE]; + + +int num_refs = -1; int curr_max_refs = PTRS_IN_PAGE; +struct ref* ref_buf[PTRS_IN_PAGE]; uint64_t ss_ref_id = 0x00FFFFFF; /* system space for ref_ids */ -/* posts for ref_buf */ -struct ref* post_buf[PTRS_IN_PAGE]; -int num_posts = 0; +int num_posts = -1; int curr_max_posts = PTRS_IN_PAGE; +struct ref* post_buf[PTRS_IN_PAGE]; -/* 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 - TODO: diff btwn vlink*/ - -struct svlink { - uint64_t ref_id; -}; - -/* A vlink is what it sounds like, a link to a vdat - TODO: model link? */ -struct vlink { - uint64_t ref_id; - char anim_name[32]; -}; - -/* Olinks are links to odats */ -struct olink { - uint64_t ref_id; -}; - -union link_t { - struct olink olink; - struct vlink vlink; - struct svlink svlink; -}; - -struct link { - int type; //1 = olink, 2 = vlink, 3 = svlink - union link_t link_t; - int cdat_idx; - int set_idx; - int ele_idx; -}; - -/* link_buf contains all the links that - we encountered during parse time that need - to be resolved to an offset at output time. - This does not include quad refs, because - those are already known to need to be resolved */ -struct link* link_buf[PTRS_IN_PAGE]; -int num_links = 0; + +int num_links = -1; int curr_max_links = PTRS_IN_PAGE; +struct link* link_buf[PTRS_IN_PAGE]; -/* 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*/ - -/* Each set has a quad_list or a list of quads. The quad_list - is the ? */ -struct quad { - int x, y, z; - uint64_t ref_id; //rgba -}; - -struct root { - int x, y, z; -}; - -struct odat { - char name[32]; - int vdat_id; - int cdat_idx; - int hitbox; - struct root root; - struct ref* refp; /* pointer to it's ref on ref_list */ - int num_quads; - struct quad quad_list[MAX_QUADS]; -}; -struct odat* odat_buf[PTRS_IN_PAGE]; -int num_odats = 0; -int curr_max_odats = PTRS_IN_PAGE; +/* The initalization function of the IR. */ +void +ir_init() +{ -/* 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 { - char 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 on 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; - struct model model_list[MAX_MODELS]; -}; + /* Init root cdat and stack */ + char root[4] = "root"; -struct vdat* vdat_buf[PTRS_IN_PAGE]; -int num_vdats = 0; -int curr_max_vdats = PTRS_IN_PAGE; + cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof(struct cdat) ); + cdat_buf[num_cdats]->idx = 0; + memmove(cdat_buf[num_cdats]->name, root, 4); + + cdat_stackp = cdat_stack; + *cdat_stackp++ = cdat_buf[num_cdats++]; +} + +//TODO: FREE MEMORY! +struct cdat* +alloc_cdat() +{ + num_cdats++; + if(curr_max_cdats <= num_cdats) + { if( (realloc((void*) cdat_buf, PTRS_IN_PAGE * 4)) == NULL) + perror("realloc cdat_buf failed"); + curr_max_cdats += PTRS_IN_PAGE; + if( (realloc( (void*) cdat_stack, PTRS_IN_PAGE * 4)) == NULL) //increase cdat_stack also + perror("realloc cdat_stack failed"); + } + if( (CURR_CDAT = (struct cdat*) malloc(sizeof (struct cdat)) ) == NULL ) + perror("malloc cdat failed"); + + return CURR_CDAT; + +} struct odat* alloc_odat () @@ -307,8 +149,6 @@ alloc_vdat if((CURR_VDAT = (struct vdat*) malloc(sizeof (struct vdat))) == NULL) perror("malloc vdat failed"); - return CURR_VDAT; - } struct link* @@ -350,6 +190,19 @@ alloc_ref return CURR_REF; } +void +inc_posts() +{ + if(num_posts >= curr_max_posts) + { if( (realloc((void*) ref_buf, PTRS_IN_PAGE * 4)) == NULL) + perror("realoc post_buf failed"); + curr_max_posts += PTRS_IN_PAGE; + } + if ((CURR_POST = (struct ref*) malloc (sizeof (struct ref))) == NULL) + perror("malloc post failed"); + +} + struct cdat* curr_cdat () @@ -363,22 +216,40 @@ curr_odat { return CURR_ODAT; } +struct vdat* +curr_vdat +() +{ + return CURR_VDAT; +} struct set* curr_set () { - return CURR_CDAT->CURR_SET; + return &CURR_CDAT->CURR_SET; } struct ele* curr_ele () { - return CURR_CDAT->CURR_SET->CURR_ELE; + return &CURR_CDAT->CURR_SET.CURR_ELE; } - struct ref* prev_ref () { return PREV_REF; -} \ No newline at end of file +} + +struct quad +curr_quad +() +{ + return CURR_QUAD; +} +struct model +curr_model +() +{ + return CURR_MODEL; +} diff --git a/src/apc/parser.y b/src/apc/parser.y index 64bed5a..12e8874 100644 --- a/src/apc/parser.y +++ b/src/apc/parser.y @@ -28,23 +28,19 @@ } //operators -%token CLOPEN // / -%token CLCLOSE // \ -%token SOPEN -%token SCLOSE -%token EOPEN -%token ECLOSE -%token VOPEN -%token VCLOSE - -%token QOPEN //! -%token QCLOSE //# -%token RT //* -%token HB -%token MOD -%token SET -%token FS -%token ELE +%token CLOPEN // ( +%token CLCLOSE // ) +%token SOPEN // { +%token SCLOSE // } +%token EOPEN // [ +%token ECLOSE // ] +%token VOPEN // / +%token VCLOSE // \ + +%token QOPEN // ! +%token QCLOSE // @ +%token RT // & +%token HB // # //nonterminal types %type olink %type ele_svlink @@ -57,6 +53,9 @@ %token REF %token SSD %token FPTR +// Change width, height, num_ptrs to NUM because +// when scanning, we can't determine which NUM +// is which. %token WIDTH %token HEIGHT %token NUM_PTRS @@ -79,7 +78,7 @@ class_list class ; class: -NAME CLOPEN {push_cdat($1);} class_block CLCLOSE {pop_cdat();}; + NAME CLOPEN {push_cdat($1);} class_block CLCLOSE {pop_cdat();}; ; class_block: @@ -119,10 +118,10 @@ quad_list ; set: -SOPEN set_label element_list set_map_data vdat SCLOSE {insert_set(); insert_vdat();}; -| SOPEN set_label element_list set_map_data set_vlink SCLOSE {insert_set();}; -| SOPEN set_label element_list set_map_data set_svlink SCLOSE {insert_set_svlink($5); insert_set(); }; -| SOPEN set_label element_list vdat SCLOSE {insert_set(); insert_vdat();}; +SOPEN set_label set_map_data element_list {alloc_vdat();} vdat SCLOSE {insert_set(); insert_set_vdatid();}; +| SOPEN set_label set_map_data element_list set_vlink SCLOSE {insert_set();}; +| SOPEN set_label set_map_data element_list set_svlink SCLOSE {insert_set_svlink($5); insert_set(); }; +| SOPEN set_label element_list {alloc_vdat();} vdat SCLOSE {insert_set(); insert_set_vdatid();}; | SOPEN set_label element_list set_vlink SCLOSE {insert_set(); } | SOPEN set_label element_list set_svlink SCLOSE {insert_set_svlink($4); insert_set();}; | SOPEN olink SCLOSE {insert_set_olink($2);}; @@ -130,7 +129,7 @@ SOPEN set_label element_list set_map_data vdat SCLOSE set_label: -HP NAME REF {insert_set_label($2,$3);}; +HP NAME REF {insert_set_label($2,$3);}; | LP NAME {insert_set_label($2, -1);}; ; @@ -166,10 +165,10 @@ REF ; element: -EOPEN ele_label hitbox root vdat ECLOSE {insert_ele(); insert_vdat();}; +EOPEN ele_label hitbox root {alloc_vdat();} vdat ECLOSE {insert_ele(); insert_ele_vdatid();}; | EOPEN ele_label hitbox root ele_vlink ECLOSE {insert_ele(); }; | EOPEN ele_label hitbox root ele_svlink ECLOSE {insert_ele_svlink($5);insert_ele(); }; -| EOPEN ele_label root vdat ECLOSE {insert_ele(); insert_vdat();}; +| EOPEN ele_label root {alloc_vdat();} vdat ECLOSE {insert_ele(); insert_ele_vdatid();}; | EOPEN ele_label root ele_vlink ECLOSE {insert_ele(); }; | EOPEN ele_label root ele_svlink ECLOSE {insert_ele_svlink($4); insert_ele(); }; | EOPEN olink ECLOSE {insert_ele_olink($2);}; @@ -181,8 +180,8 @@ VOPEN model_list VCLOSE model_list: model_list model -| model -; +| model + ; model: spritesheet LP