X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fwebcc.git;a=blobdiff_plain;f=src%2Fapc%2Firmem.c;h=415399cb5a62f077f5bdc0be2058d05666940f5c;hp=3b62201dbe608278b78fb14dfa1b76c38e8cfdce;hb=301cac5f6e2edcecf2e1bd89aee5182130a213fc;hpb=98197290ac44b0c9960ba2edd60a9ec5515aa181 diff --git a/src/apc/irmem.c b/src/apc/irmem.c index 3b62201..415399c 100644 --- a/src/apc/irmem.c +++ b/src/apc/irmem.c @@ -1,723 +1,374 @@ -/*!@file - \brief IR Memory Implementation - \details Intermediary memory management - \author Jordan Lavatai - \date Aug 2016 - ----------------------------------------------------------------------------*/ -#include #include -#include //uint64_t -#include //memmove -#include //malloc +#include +#include +#include +#include +#include #include +#include + +struct cdat* +alloc_cdat(void); +struct odat* +alloc_odat(void); +struct vdat* +alloc_vdat(void); +struct link* +alloc_link(void); +struct ref* +alloc_ref(void); +struct cdat* +curr_cdat(void); +struct odat* +curr_odat(void); +struct vdat* +curr_vdat(void); +struct map* +curr_map(void); +struct set* +curr_set(void); +struct ref* +curr_ref(void); +struct model* +curr_model(void); +void +inc_posts(void); + +#define PAGES_PER_CHUNK 16 + +//"type free" chunk stacking +struct chunk_stack +{ void* chunks[MAX_CHUNKS]; + void* *csp; //chunk stack pointer + void* dsp[MAX_CHUNKS]; //dat stack pointer (per chunk) + int chunk_size; //size of a chunk (including its forfeited page) + int max_dats; //number of dats per chunk for this stack +} ocs, vcs, ccs, rcs, lcs, pcs, mcs; //odat, vdat, cdat,map, ref, link, post stacks + +//type safety handled by macro expansion (do not call these directly from code, make dependent macros for access to these) +#define CHUNKS_LEN(STACK) ((STACK).csp - (STACK).chunks) +#define CURRENT_CHUNK(STACK) ((STACK).chunks[CHUNKS_LEN(STACK) - 1]) +#define CHUNKS_FULL(STACK) ( (STACK).csp >= \ + (STACK).chunks + MAX_CHUNKS * (STACK).chunk_size) +#define CURRENT_DSP(STACK,TYPE) ((TYPE*) ((STACK).dsp[CHUNKS_LEN(STACK) - 1])) +#define DATA_FULL(STACK,TYPE) ((void*) CURRENT_DSP(STACK,TYPE) >= \ + (CURRENT_CHUNK(STACK) + (STACK).chunk_size)) +#define CSP_PUSH(STACK) (*(++(STACK).csp) = malloc((STACK).chunk_size)) +#define CURRENT_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 1]) +#define PREVIOUS_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 2]) +#define ALLOC_DAT(STACK,TYPE) (++CURRENT_DATP(STACK,TYPE)) +#define INIT_STACK(STACK,TYPE) \ + { int i; \ + (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \ + (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \ + CSP_PUSH(STACK); \ + for( i = 0; i < MAX_CHUNKS; i++){ \ + (STACK).dsp[i] += pagesize; \ + } \ + } +//Stack-specific macros (called directly from code (safety enforcement) +#define INIT_ODAT() (INIT_STACK(ocs, struct odat)) +#define CURRENT_ODAT() (CURRENT_DATP(ocs,struct odat)) +#define ODAT_FULL() (DATA_FULL(ocs,struct odat)) +#define ODAT_ALLOC() (ALLOC_DAT(ocs,struct odat)) +#define OCS_FULL() (CHUNKS_FULL(ocs)) +#define INIT_VDAT() (INIT_STACK(vcs, struct vdat)) +#define CURRENT_VDAT() (CURRENT_DATP(vcs,struct vdat)) +#define VDAT_FULL() (DATA_FULL(vcs,struct vdat)) +#define VDAT_ALLOC() (ALLOC_DAT(vcs,struct vdat)) +#define VCS_FULL() (CHUNKS_FULL(vcs)) +#define INIT_CDAT() (INIT_STACK(ccs, struct cdat)) +#define CURRENT_CDAT() (CURRENT_DATP(ccs,struct cdat)) +#define CDAT_FULL() (DATA_FULL(ccs, struct cdat)) +#define CDAT_ALLOC() (ALLOC_DAT(ccs, struct cdat)) +#define CCS_FULL() (CHUNKS_FULL(ccs)) +#define INIT_MAP() (INIT_STACK(mcs, struct map)) +#define CURRENT_MAP() (CURRENT_DATP(mcs, struct map)) +#define MAP_FULL() (DATA_FULL(mcs, struct map)) +#define MAP_ALLOC() (ALLOC_DAT(mcs, struct map)) +#define MCS_FULL() (CHUNKS_FULL(mcs)) +#define INIT_LINK() (INIT_STACK(lcs, struct link)) +#define CURRENT_LINK() (CURRENT_DATP(lcs,struct link)) +#define LDAT_FULL() (DATA_FULL(lcs, struct link)) +#define LDAT_ALLOC() (ALLOC_DAT(lcs, struct link)) +#define LCS_FULL() (CHUNKS_FULL(lcs)) +#define INIT_POST() (INIT_STACK(rcs, struct ref)) +#define CURRENT_POST() (CURRENT_DATP(pcs,struct ref)) +#define POST_FULL() (DATA_FULL(pcs,struct ref)) +#define POST_ALLOC() (ALLOC_DAT(pcs,struct ref)) +#define PCS_FULL() (CHUNKS_FULL(pcs)) +#define INIT_REF() (INIT_STACK(rcs, struct ref)) +#define CURRENT_REF() (CURRENT_DATP(rcs,struct ref)) +#define PREVIOUS_REF() (PREVIOUS_DATP(rcs, struct ref)) +#define REF_FULL() (DATA_FULL(rcs,struct ref)) +#define REF_ALLOC() (ALLOC_DAT(rcs,struct ref)) +#define RCS_FULL() (CHUNKS_FULL(rcs)) +//Metadata +#define CURRENT_SET() (CURRENT_CDAT()->set_list[CURRENT_CDAT()->num_sets]) +//#define CURRENT_QUAD() (CURRENT_MAP()->quad_list[CURRENT_MAP()->num_quads]) +//#define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models]) + + + +long pagesize; -#define CURR_CDAT (*cdat_stackp) -#define CURR_SET set_list[CURR_CDAT->num_sets] -#define CURR_ELE ele_list[CURR_CDAT->CURR_SET.num_ele] -#define PREV_REF (ref_buf[num_refs-1]) -#define CURR_REF (ref_buf[num_refs]) -#define PREV_ODAT (odat_buf[num_odats-1]) -#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_LINK (link_buf[num_links]) -#define CURR_POST (post_buf[num_posts]) +int num_cdats = 0; -void -inc_odat(void); -void -inc_vdat(void); -void -inc_link(void); -void -inc_ref(void); -void -ir_init(void); -void -malloc_cdat(void); - - - -/* 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. */ - -struct cdat* cdat_stack[PTRS_IN_PAGE]; +struct cdat* cdat_stack[MAX_CLASSES]; 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 curr_max_refs = 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 curr_max_posts = 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 curr_max_links = 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; - -/* 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]; -}; - -struct vdat* vdat_buf[PTRS_IN_PAGE]; -int num_vdats = 0; -int curr_max_vdats = PTRS_IN_PAGE; - - -/* The initalization function of the IR. Mallocs the - first c/v/odat and the first links and refs and - inits the cdat_stack */ -void -ir_init() -{ - - /* Init root cdat and stack */ - char root[4] = "root"; - 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++]; +int num_vdats = 0; - /* Init first odat */ - if( (CURR_ODAT = (struct odat*) malloc(sizeof(struct odat))) == NULL) - perror("malloc first odat failed"); +int num_maps = 0; - /* init first vdat*/ - if( (CURR_VDAT = (struct vdat*) malloc(sizeof(struct vdat))) == NULL) - perror("malloc first vdat failed"); +int num_refs = 0; +int ss_ref_id = 0x0FFFFFFF; /* system space for ref_ids */ - /* Init first ref */ - if( (CURR_REF = (struct ref*) malloc(sizeof(struct ref))) == NULL) - perror("malloc first ref failed"); +int num_posts = 0; - /* Init first link */ - if( (CURR_LINK = (struct link*) malloc(sizeof(struct link))) == NULL) - perror("malloc first link failed"); +int num_links = 0; - /* Init first post */ - if( (CURR_POST = (struct ref*) malloc(sizeof(struct ref))) == NULL) - perror("malloc first post failed"); -} -//TODO: FREE MEMORY! -void -malloc_cdat() +/* The initalization function of the IR. */ +int +ir_init() { - 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"); + char root[4] = "root"; -} + pagesize = sysconf(_SC_PAGESIZE); -/* 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 - we can access the cdat during processing of that - cdats sets and elements, a requirement because the - nature of recursive classes prevents us from accessing - the cdat based on the previous index into cdat_buf, - which is a list of all allocated cdats*/ -void -push_cdat -( char* name -) -{ - malloc_cdat(); + INIT_CDAT(); + *cdat_stackp = CURRENT_CDAT(); + + memmove((*cdat_stackp)->name, root, 32); - memmove(cdat_buf[num_cdats]->name, name, 32); - cdat_buf[num_cdats]->idx = num_cdats; + INIT_ODAT(); + INIT_VDAT(); + INIT_MAP(); + INIT_LINK(); + INIT_REF(); + INIT_POST(); - /* Set the cdat as a class of the previous cdat */ - (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes++] = cdat_buf[num_cdats]; - /* Push the cdat onto the cdat_stack */ - *++cdat_stackp = cdat_buf[num_cdats++]; + return 0; } void -pop_cdat -() +ir_quit() { - *cdat_stackp = NULL; - cdat_stackp--; -} + int i; -void -inc_posts -() -{ - num_posts++; - if(num_posts >= curr_max_posts) - { if( (realloc((void*) post_buf, PTRS_IN_PAGE * 4)) == NULL) - perror("realloc post_buf failed"); - curr_max_posts += PTRS_IN_PAGE; + for(i = 0; i < CHUNKS_LEN(ccs) ; i++) + { + free(ccs.chunks[i]); } - if( (CURR_POST = (struct ref*) malloc(sizeof (struct ref))) == NULL) - perror("malloc post failed"); - -} -void -inc_odat -() -{ - num_odats++; - if(num_odats >= curr_max_odats) - { if( (realloc((void*) odat_buf, PTRS_IN_PAGE * 4)) == NULL) - perror("realloc odat_buf failed"); - curr_max_odats += PTRS_IN_PAGE; + for(i = 0; i < CHUNKS_LEN(ocs); i++) + { + free(ocs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(vcs) ; i++) + { + free(vcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(rcs); i++) + { + free(rcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(lcs); i++) + { + free(lcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(pcs); i++) + { + free(pcs.chunks[i]); } - if( (CURR_ODAT = (struct odat*) malloc(sizeof (struct odat))) == NULL) - perror("malloc odat failed"); } -void -inc_vdat -() +struct cdat* +alloc_cdat() { - num_vdats++; - if(num_vdats >= curr_max_vdats) - { if( (realloc((void*) vdat_buf, PTRS_IN_PAGE * 4)) == NULL) - perror("realloc vdat_buf failed"); - curr_max_vdats += PTRS_IN_PAGE; + num_cdats++; + if(CDAT_FULL()) + { if(CCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) cdats ", num_cdats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(ccs); } - if((CURR_VDAT = (struct vdat*) malloc(sizeof (struct vdat))) == NULL) - perror("malloc vdat failed"); + else + CDAT_ALLOC(); + return CURRENT_CDAT(); } -void -inc_link +//these should probably be inline +struct odat* +alloc_odat () { - num_links++; - if(num_links >= curr_max_links) - { if( (realloc((void*) link_buf, PTRS_IN_PAGE * 4)) == NULL) - perror("realloc vdat_buf failed"); - curr_max_links += PTRS_IN_PAGE; + num_odats++; + if(ODAT_FULL()) + { if(!OCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) odats ", num_odats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(ocs); } - if((CURR_LINK = (struct link*) malloc(sizeof (struct link))) == NULL) - perror("malloc link failed"); + else + ODAT_ALLOC(); + + return CURRENT_ODAT(); } -void -inc_ref +struct vdat* +alloc_vdat () -{ - - if(num_refs % 16 == 0) - { CURR_POST = CURR_REF; - inc_posts(); - } - - num_refs++; - if(num_refs >= curr_max_refs) - { if( (realloc((void*) ref_buf, PTRS_IN_PAGE * 4)) == NULL) - perror("realloc ref_buf failed"); - curr_max_refs += PTRS_IN_PAGE; +{ num_vdats++; + if(VDAT_FULL()) + { if(!VCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) vdats ", num_vdats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(vcs); } - if((CURR_REF = (struct ref*) malloc(sizeof (struct ref))) == NULL) - perror("malloc ref failed"); -} -/* 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. */ - -void -insert_set_label -( char* name, - uint64_t ref_id -) -{ - memmove(CURR_CDAT->CURR_SET.name,name,32); - memmove(&CURR_CDAT->CURR_SET.ref_id,&ref_id,64); + else + VDAT_ALLOC(); -} -void -insert_set_olink -( uint64_t ref_id -) -{ - CURR_CDAT->CURR_SET.cdat_idx = CURR_CDAT->idx; - CURR_CDAT->CURR_SET.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; - - inc_link(); + return CURRENT_VDAT(); } -void -insert_set_vlink -( uint64_t ref_id, - char* anim_name -) -{ - /* Insert vlink into link_stack so that it gets processed at - output time */ - CURR_LINK->cdat_idx = CURR_CDAT->idx; - CURR_LINK->set_idx = CURR_CDAT->num_sets; - CURR_LINK->type = 2; - CURR_LINK->link_t.vlink.ref_id = ref_id; - memmove(CURR_LINK->link_t.vlink.anim_name, anim_name, 32); - +struct map* +alloc_map +() +{ num_maps++; + if(MAP_FULL()) + { if(!MCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) maps ", num_maps); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(mcs); + } + else + MAP_ALLOC(); + return CURRENT_MAP(); } -void -insert_set_svlink -( uint64_t ref_id -) -{ - /* Insert vlink into link_stack so that it gets processed at - output time */ - CURR_LINK->cdat_idx = CURR_CDAT->idx; - CURR_LINK->set_idx = CURR_CDAT->num_sets; - CURR_LINK->type = 3; - CURR_LINK->link_t.svlink.ref_id = ref_id; - -} - -/* At the point of reducing to a set, most of the - sets odat information has already been populated - during the reduction of its right hand side - non terminals (hitbox, root, quad_list). */ -void -insert_set +struct link* +alloc_link () -{ - uint64_t ref_id; - - ref_id = CURR_CDAT->CURR_SET.ref_id; - - CURR_CDAT->CURR_SET.cdat_idx = CURR_CDAT->idx; - memmove(CURR_ODAT->name, CURR_CDAT->CURR_SET.name, 32); - CURR_CDAT->num_sets++; - - CURR_ODAT->cdat_idx = CURR_CDAT->idx; - CURR_ODAT->refp = CURR_REF; - - - CURR_REF->lastref = PREV_REF; - PREV_REF->nextref = CURR_REF; - CURR_REF->odatp = CURR_ODAT; - - - if(ref_id == -1) /* user did not define a ref_id so */ - { ref_id = ss_ref_id; - ss_ref_id++; +{ num_links++; + if(LDAT_FULL()) + { if(!LCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) links ", num_links); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(lcs); } + else + LDAT_ALLOC(); - CURR_REF->ref_id = ref_id; + return CURRENT_LINK(); - inc_ref(); - inc_odat(); } -/* 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). Because insert_set/ele is always - called before insert_vdat, and thus increments the CURR_ODAT to be the next - ODAT to be populated, insert_vdat() targets the last ODAT that was populated, - via PREV_ODAT. */ -void -insert_vdat +struct ref* +alloc_ref () -{ - PREV_ODAT->vdat_id = num_vdats; //NULL for vlink, svlink - inc_vdat(); -} - -/* Populates both the odat name and ref_id - for element. */ -void -insert_ele_label -( char* name, - uint64_t ref_id -) -{ - memmove(CURR_CDAT->CURR_SET.CURR_ELE.name, name, 32); - memmove(&CURR_CDAT->CURR_SET.ele_list[CURR_CDAT->CURR_SET.ref_id].ref_id, &ref_id, 64); -} - -void -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 - 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++; - -} +{ num_refs++; + if(REF_FULL()) + { if(!RCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) refs ", num_refs); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(rcs); + } + else + REF_ALLOC(); -void -insert_ele_vlink -( uint64_t ref_id, - char* anim_name -) -{ - /* 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); + if(num_refs % 16 == 0) + { CURRENT_POST() = CURRENT_REF(); + inc_posts(); + } + return CURRENT_REF(); } void -insert_ele_svlink -( uint64_t ref_id -) -{ - - 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; - +inc_posts() +{ num_posts++; + if(POST_FULL()) + { if(!PCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) refs ", num_posts); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(pcs); + } + else + POST_ALLOC(); } -//Insert element into odat_buf and cdatpages -void -insert_ele() +struct cdat* +curr_cdat +() { - 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; - - 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(); - + return (*cdat_stackp); } -void -insert_framesheet -( char direction, - char* name, - uint64_t ref_id, - int height , - int width, - int num_frames -) +struct odat* +curr_odat +() { - 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++; + return CURRENT_ODAT(); } - -void -insert_quad -( int x, - int y, - int z, - uint64_t ref_id -) -#define CURR_QUAD (CURR_ODAT->quad_list[CURR_ODAT->num_quads]) +struct vdat* +curr_vdat +() { - CURR_QUAD.x = x; - CURR_QUAD.y = y; - CURR_QUAD.z = z; - CURR_QUAD.ref_id = ref_id; - CURR_ODAT->num_quads++; + return CURRENT_VDAT(); } - -/* Inserting the hitbox into the set - odat. Elements that don't have - a hitbox will use the sets root. */ -void -insert_hitbox -( int hitbox -) +struct set* +curr_set +() { - CURR_ODAT->hitbox = hitbox; + return &CURRENT_SET(); } - -/* Inserting the root into the set - odat. Elements that don't have - a root will use the sets root. */ -void -insert_root -( int x, - int y, - int z -) +struct ref* +curr_ref +() { - - CURR_ODAT->root.x = x; - CURR_ODAT->root.y = y; - CURR_ODAT->root.z = z; + return CURRENT_REF(); } - -void -insert_frame_pointer -( char direction, - void* frame -) +struct map* +curr_map +() { - CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].frames[CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames++] = frame; + return CURRENT_MAP(); } - +/* struct quad* */ +/* curr_quad */ +/* () */ +/* { */ +/* return &CURRENT_QUAD(); */ +/* } */ +/* struct model* */ +/* curr_model */ +/* () */ +/* { */ +/* return &CURRENT_MODEL(); */ +/* } */