X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fir.c;h=cb5fafd56f715d52a9341736007685863b24daca;hp=8652ddca2b733d21d6e9a3e7cc5d6281308e2e61;hb=892bb35058d0fd8b92f8f3fa0fbdee4f00aa57f0;hpb=1c75266c959f8168fb6a73b6fef22fc91a5affc7 diff --git a/src/ir.c b/src/ir.c old mode 100755 new mode 100644 index 8652ddc..cb5fafd --- a/src/ir.c +++ b/src/ir.c @@ -4,1333 +4,708 @@ \author Jordan Lavatai \date Aug 2016 ----------------------------------------------------------------------------*/ -#include -#include -#include //uint8_t as a char -#include //u32_cpy +/* Standard */ +#include //exit, malloc +#include //print +#include //va_args #include //uint64_t -#include //memset -#include //u8_* functions +#include //memset, str* +/* Unicode */ +#include //u8_* functions +#include //uint8_t as a char +#include //u32_cpy +#include //ulc_fprintf +/* Local */ +#include "print.h" #include "apc.h" - - -extern -int -name_u8_cpy(struct name*, struct name*); - -extern -int -name_u8_cmp(struct name*, struct name*); - -extern -int -name_u8_set(struct name*, ucs4_t); - -int -ir_init(void); -struct cdat* -alloc_cdat(void); -struct odat* -alloc_odat(void); -void -alloc_vdat(void); -struct link* -alloc_link(void); -struct ref* -alloc_ref(void); -struct set* -alloc_set(void); -struct cdat* -curr_cdat(void); -struct odat* -curr_odat(void); -struct vdat* -curr_vdat(void); -struct map* -curr_map(void); -struct set* -curr_cdat_set(void); -struct set* -curr_set(int); -struct ref* -curr_ref(void); -struct model* -curr_model(void); - -/* ir.c */ -void -inc_posts(void); -void -push_cdat(struct name*); -void -pop_cdat(void); -void -insert_link_name(struct name*); -void -insert_link_namelist(struct name*); -void -insert_ss_name(struct name*); -void -insert_ss_namelist(struct name*); -void -insert_mlink(struct name*, int); -void -insert_vlink(struct name*, int); -void -insert_ref(struct odat*, int); -void -alloc_vdat(void); -void -insert_vdat(void); -void -insert_map(struct name*, int, int, int, int, uint8_t*); -void -insert_framesheet(struct name*, int, int, int, int, uint8_t*); - - - -//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_SET() (INIT_STACK(scs, struct set)) -#define CURRENT_SET() (CURRENT_DATP(scs, struct set)) -#define SET_FULL() (DATA_FULL(scs, struct set)) -#define SET_ALLOC() (ALLOC_DAT(scs, struct set)) -#define SCS_FULL() (CHUNKS_FULL(scs)) -#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_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models]) - - - -/* 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 -/* Cdats: A cdat is a class data structure. Cdats serve as the central */ -/* data types of the IR. 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? */ -/* TODO: Talk more about cdat set structure */ -struct cdat { - struct name name; - int idx; - int num_classes; - int num_sets; - struct cdat* class_list[MAX_CLASSES]; - struct set* set_list[MAX_SETS]; +#include "ir.h" +#undef do_error +#define do_error(...) exit(-1) +#define XXH_PRIVATE_API +#include "../xxHash/xxhash.h" +/* Public */ +int ir_init(void); +void ir_quit(void); +void ir_test(void); +int ir_linker(void); +int ir_condenser(void); +/* Memory allocation structures */ +struct pagenode_t; +struct pagenode_header_t { + struct pagenode_t* next; + char* head; }; - - -/* Sets: What is a set? - Instantiation? - Associations? - Containment? - Usage? - The set is populated at parse time AFTER the elements are populated, due to - the nature of bottom up parsing. */ -struct set { - int cdat_idx; - int num_sets; - struct set* set_list[MAX_SETS]; +struct pagenode_t { + struct pagenode_header_t header; + char root[]; }; - -/* Refs: Each set/ele has a reference to its object data (odat) through a refid. - refids 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; //TODO: Is this needed? - struct ref* nextref; - struct ref* lastref; - struct odat* odatp; - int refid; //0xFFFFFF->digit +struct pagelist_t { + struct pagenode_t* root, * head; + size_t pagesize; }; - -/* 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 refid 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 refid that was stored for some object (if the refid exists), - and creating a relative pointer from the original object to the data that - was linked */ - -/* TODO: Explain links more betta */ - -struct olink { - int src_refid; +#define SYS_PAGESIZE (sys_pagesize) +#define NAME_PAGESIZE (APC_NAME_MAX * 1024) +#define PL_HEADERSIZE (sizeof(struct pagenode_header_t)) +#define PL_HEADSIZE(_PL) (_PL.head->header.head - _PL.head->root) +#define PL_HEADMEM(_PL) (_PL.pagesize - PL_HEADERSIZE - PL_HEADSIZE(_PL)) +/* Set data mem */ +enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; +struct ir_namelist_t; +struct ir_namelist_t +{ struct ir_namelist_t* nextsib; + uint8_t* name; }; - -struct vlink { - int src_refid; - struct name src_animname; - struct name src_namelist[MAX_DEPTH]; +struct ir_classld_t +{ struct ir_class_t* root_class; + struct ir_namelist_t* namelist, * namelist_head; }; - -struct mlink { - int src_refid; - struct name src_mapname; - struct name src_namelist[MAX_DEPTH]; - +struct ir_setld_t +{ struct ir_classld_t* classld; + long long ref; + struct ir_namelist_t* namelist, * namelist_head; }; - -union link_t { - struct vlink vlink; - struct mlink mlink; - struct olink olink; +struct ir_setdata_header_t +{ enum dtype type; + uint8_t* src_filename, * data_name; + union ir_setdata_t* nextsib; }; - - -/* From: src odat ()To: dest odat (refid)*/ -struct link { - int type; //1 = olink, 2 = vlink, 3 = mlink - union link_t link_t; - int dest_refid; //if it exists - struct odat* dest_odatp; - +struct ir_frameinfo_t +{ int facing, w, h; }; +struct ir_framedata_t +{ struct ir_setdata_header_t header; + struct ir_frameinfo_t frameinfo; }; - -struct map { - struct name name; - int height; - int width; - uint8_t filepath[FPATH_MAX]; +struct ir_framebox_t +{ struct ir_setdata_header_t header; + struct ir_framedata_t framesheets[FACING_MAX]; + struct ir_framedata_t mapsheets[FACING_MAX]; }; - -/* 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 { - struct name name; - int refid; - int ismap; - int vdat_idx; - struct link* linkp; - struct vdat* vdatp; - struct odat* parent_odatp; // odat == set ? null : set refid - struct ref* refp; /* pointer to it's ref on ref_list */ - struct map map; //only valid if odat ismap - +struct ir_simplex_t { struct ir_setdata_header_t header; }; +struct ir_link_t +{ struct ir_setdata_header_t header; + struct ir_classld_t* classld; + struct ir_setld_t* setld; + enum ltype type; }; - -/* 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; - +union ir_setdata_t +{ struct ir_setdata_header_t header; + struct ir_framebox_t framebox; + struct ir_framedata_t framesheet; + struct ir_framedata_t mapsheet; + struct ir_simplex_t audio; + struct ir_link_t link; }; - -/* A model is a collection of framesheets for every - direction (N,W,S,E,NW,NE,SW,SE)*/ -/* NAMED spritesheet */ -struct model { - struct name name; - uint8_t filepath[PATH_MAX]; - struct framesheet spritesheet[8]; //one for each +struct ir_class_t +{ struct ir_class_t* nextchild, * nextsib; + struct ir_set_t* root_set; + uint8_t* name; }; - -/* 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 map 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[FNAME_MAX]; - int height; - int width; - uint8_t filepath[FPATH_MAX]; - struct model model_list[MAX_MODELS]; +struct ir_set_t +{ struct ir_set_t* nextchild, * nextsib; + uint32_t ref; + uint8_t* name; + struct ir_framebox_t* frameboxes; + struct ir_simplex_t* audio; + struct ir_link_t* links; }; - - -struct set_frame -{ struct name namelist[MAX_DEPTH]; - int num_names; - struct set* setp; - struct odat* odatp; -} ; - - - -struct set_stack -{ struct set_frame set_frames[MAX_DEPTH]; - int curr_depth; //used to get most recently created set/odat + to check for undefined parents of namelists -}; - - -//"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, scs; //odat, vdat, cdat, ref, link, post stacks - - - - -/* 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[MAX_CLASSES]; -struct cdat** cdat_stackp; - -struct set_stack ss; -struct name set_namelist[MAX_DEPTH]; -int set_numnames = 0; - -struct name link_namelist[MAX_DEPTH]; -int link_numnames = 0; - -int num_cdats = 0; -int num_odats = 0; -int num_vdats = 0; -int num_sets = 0; -int num_refs = 0; -int ss_refid = 0x0FFFFFFF; /* system space for refids */ -int num_posts = 0; -int num_links = 0; -int num_models = 0; -long pagesize = 0; - - -/* The initalization function of the IR. */ -int -ir_init() -{ struct name name; - - - uint8_t root[4] = "root"; - - u8_stpncpy(name.name, root, 4); - - pagesize = sysconf(_SC_PAGESIZE); - printf("pagesize is %l\n", pagesize); - - INIT_CDAT(); - *cdat_stackp = CURRENT_CDAT(); - name_u8_cpy(&(*cdat_stackp)->name, &name); - - INIT_ODAT(); - INIT_VDAT(); - VDAT_ALLOC(); //NULL vdat - VDAT_ALLOC(); //First vdat req. because alloc_vdat happens after vdat is reduced - INIT_SET(); - INIT_LINK(); - INIT_REF(); - INIT_POST(); - - +/* Functions */ +static inline +struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*,uint8_t*); +static inline +union ir_setdata_t* ir_framedata (enum dtype,const uint8_t*,apc_facing,int,int); +static inline +int bytes_identical(const uint8_t*,const uint8_t*); +static inline +int classnames_identical(const uint8_t*,const uint8_t*); +static +void* stack_alloc(size_t); +#define struct_alloc(_T) ((struct _T*) stack_alloc(sizeof(struct _T))) +#define struct_clear(_S) (memset((_S), 0, sizeof(*(_S)))) +static +uint8_t* name_alloc(const uint8_t*); +static +uint8_t* classname_alloc(const uint8_t*); +static inline +void* pagelist_pop(struct pagelist_t*,size_t); +#define $($)#$ +#define pagelist_alloc(pagelist) do { \ + pagelist.head->header.next = (struct pagenode_t*) malloc(pagelist.pagesize); \ + if (pagelist.head->header.next == NULL) \ + eprintf("Memory allocation error\n"); \ + struct_clear(pagelist.head->header.next); \ + pagelist.head = pagelist.head->header.next; \ + pagelist.head->header.head = pagelist.head->root; \ + } while (0) +#define pagelist_init(pagelist,size) do { \ + pagelist.pagesize = size; \ + pagelist.root = (struct pagenode_t*) malloc(size); \ + if (pagelist.root == NULL) \ + eprintf("Memory allocation error\n"); \ + struct_clear(pagelist.root); \ + pagelist.head = pagelist.root; \ + pagelist.head->header.head = pagelist.head->root; \ + } while (0) +static +void pagenode_free(struct pagenode_t*); +#define REFHASH(ref) (XXH32(&ref, sizeof(uint32_t), 0xCEED) & 0xCFF) + +extern //apc.c +long sys_pagesize; +static +struct pagelist_t datapages, namepages, refhashpages; +static +struct ir_class_t root_class = { .name = (uint8_t*)"." }; + +/* Init */ +int ir_init +( void ) +{ pagelist_init(datapages, (size_t)SYS_PAGESIZE); + pagelist_init(namepages, (size_t)NAME_PAGESIZE); + pagelist_init(refhashpages, (size_t)SYS_PAGESIZE); return 0; - } -void -ir_quit() -{ - int i; - - for(i = 0; i < CHUNKS_LEN(ccs) ; i++) - { - free(ccs.chunks[i]); - } - 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]); - } - +/* Quit/Cleanup */ +void ir_quit +( void ) +{ pagenode_free(datapages.root); + pagenode_free(namepages.root); + pagenode_free(refhashpages.root); } -struct cdat* -alloc_cdat() -{ - 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); - } - else - CDAT_ALLOC(); - - return CURRENT_CDAT(); +/* Recursively clean pagenode linked list, freeing last first */ +static +void pagenode_free +( struct pagenode_t* pagenode ) +{ if (pagenode->header.next != NULL) + pagenode_free(pagenode->header.next); + free(pagenode); } -//these should probably be inline -struct odat* -alloc_odat -() -{ - 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); - } - else - ODAT_ALLOC(); - - return CURRENT_ODAT(); -} - -void -alloc_vdat -() -{ 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); - } - else - VDAT_ALLOC(); - - +/* Link */ +int ir_linker +( void ) +{ + return 0; } -struct set* -alloc_set -() -{ num_sets++; - if(SET_FULL()) - { if(!SCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) sets ", num_sets); - exit(EXIT_FAILURE); - } - else - CSP_PUSH(scs); +/* Condense */ +int ir_condenser +( void ) +{ return 0; } + +/* Return the class's name string */ +uint8_t* ir_class_name +( struct ir_class_t* class ) +{ return class->name; } + +/* Return a pointer to the root class */ +struct ir_class_t* ir_class_root +( void ) +{ return &root_class; } + +/* Add a subclass to a class + Attempts to create a new subclass in the provided class, returning + the class if it already exists +*/ +struct ir_class_t* ir_class_addchild +( struct ir_class_t* class, + const uint8_t* name +) +{ struct ir_class_t* iter; + if (class->nextchild == NULL) + { class->nextchild = struct_alloc(ir_class_t); + struct_clear(class->nextchild); + class->nextchild->name = classname_alloc(name); + return class->nextchild; } - else - SET_ALLOC(); - - return CURRENT_SET(); -} - - -struct link* -alloc_link -() -{ 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); + iter = class->nextchild; + if (iter->name == NULL) + eprintf("Null name pointer in class %p\n", iter); + if (name == NULL) + eprintf("Null child added to class %s\n", iter->name); + check: + if (classnames_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - else - LDAT_ALLOC(); - - return CURRENT_LINK(); - -} - -struct ref* -alloc_ref -() -{ 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); + iter->nextsib = struct_alloc(ir_class_t); + struct_clear(iter->nextsib); + iter->nextsib->name = classname_alloc(name); + return iter->nextsib; +} + +/* Add a set to a class + Attempts to create a new root set in the specified class, returning + the set if it already exists +*/ +struct ir_set_t* ir_class_addset +( struct ir_class_t* class, + const uint8_t* name +) +{ struct ir_set_t* iter; + if (class->root_set == NULL) + { class->root_set = struct_alloc(ir_set_t); + struct_clear(class->root_set); + class->root_set->name = name_alloc(name); + return class->root_set; } - else - REF_ALLOC(); - - - if(num_refs % 16 == 0) - { CURRENT_POST() = CURRENT_REF(); - inc_posts(); + iter = class->root_set; + if (iter->name == NULL) + eprintf("Null name pointer in class %p\n", iter); + if (name == NULL) + eprintf("Null set added to class %U\n", iter->name); + check: + if (bytes_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - - return CURRENT_REF(); -} - -void -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); + iter->nextsib = struct_alloc(ir_set_t); + struct_clear(iter->nextsib); + iter->nextsib->name = name_alloc(name); + return iter->nextsib; +} + +struct ir_set_t* ir_set_from_ref +( uint32_t ref ) +{ uint16_t hash; + struct ir_set_t** iters; + struct pagenode_t* iterp; + iterp = refhashpages.root; + hash = REFHASH(ref); + do + iters = ((struct ir_set_t**) iterp->root) + hash; + while (*iters != NULL && (*iters)->ref != ref && (iterp = iterp->header.next) != NULL); + return *iters; +} + + +/* Add a set to a set + Attempts to create a new subset of the specified set, returning the + child if it already exists +*/ +struct ir_set_t* ir_set_addchild +( struct ir_set_t* set, + const uint8_t* name +) +{ struct ir_set_t* iter; + if (set->nextchild == NULL) + { set->nextchild = struct_alloc(ir_set_t); + struct_clear(set->nextchild); + set->nextchild->name = name_alloc(name); + return set->nextchild; } - else - POST_ALLOC(); - -} - -struct cdat* -curr_cdat -() -{ - return (*cdat_stackp); -} - -struct odat* -curr_odat -() -{ - return CURRENT_ODAT(); -} - -struct vdat* -curr_vdat -() -{ - return CURRENT_VDAT(); -} - -struct set* -curr_cdat_set -() -{ - return CURRENT_SET(); -} - -struct set* -curr_set -(int depth) -{ int i; - struct set* setp; - - for(i = 0; i <= depth; i++) - { if(!(setp = setp->set_list[setp->num_sets])) - { printf("You are trying to access a set that does not exist irmem.c\n"); - return NULL; - } + iter = set->nextchild; + if (name == NULL) + eprintf("Null child added to set %s\n", iter->name); + if (iter->name == NULL) + eprintf("Null name pointer in set %p\n", iter); + check: + if (bytes_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - - - return setp; -} - -struct ref* -curr_ref -() -{ - return CURRENT_REF(); -} -struct ref* -prev_ref -() -{ - return PREVIOUS_REF(); -} -struct model* -curr_model -() -{ - return &CURRENT_MODEL(); -} - -/* IR.C*/ -void -push_cdat -( name ) - struct name* name; -{ - struct cdat* curr_cdatp; - - curr_cdatp = alloc_cdat(); - - name_u8_cpy(&curr_cdatp->name, name); - curr_cdatp->idx = num_cdats; - - /* Set the cdat as a subclass of the previous cdat */ - (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes] = curr_cdatp; - /* Push the cdat onto the cdat_stack */ - *++cdat_stackp = curr_cdatp; - -} - -void -pop_cdat -() -{ - cdat_stackp--; -} - - -void -insert_set_name -( name ) - struct name* name; -{ - //Push name onto current namelist, set the set_namelist. - name_u8_cpy(&set_namelist[set_numnames++], name); - - -} - - -void -insert_set_namelist -( name ) - struct name* name; -{ int depth, nameidx, i; - - insert_set_name(name); - - //Check if entire string matches first? Only possible if namelist is contiguous (uint8_t strings seperated by \0) - //Create odats/sets for each name in namelist where nameidx > ns_depth - //first check if any parts of namelist matches what is currently on namestack - //we can gauruntee that from ns_depth + 1 -> set_numnames namelists dont match. x - - - //if name_list doesnt match, from the first depth at which namelist doesnt match - //remove the nameframes namelist (zero out ones below?) and replace with current namelist, - //then allocate a new odat and set it to the current set_frame. - for( depth = 0; depth < set_numnames ; depth++ ) - { for (nameidx = 0; nameidx <= depth; nameidx++) - { if( name_u8_cmp(&set_namelist[nameidx], &ss.set_frames[depth].namelist[nameidx]) != 0 ) - { /* Populate the namelist of the set at the current depth */ - for(i = 0; i <= depth; i++) - name_u8_cpy(&ss.set_frames[depth].namelist[i], &set_namelist[i]); - - /* Alloc set and odat */ - ss.set_frames[depth].odatp = alloc_odat(); - ss.set_frames[depth].setp = alloc_set(); - - /* populate set/odat name and cdat_idx */ - name_u8_cpy(&ss.set_frames[depth].odatp->name, &set_namelist[depth]); - ss.set_frames[depth].setp->cdat_idx = ( *cdat_stackp)->idx; - - /* Insert allocated set and odat into their respective trees if there is a depth - (they have parents) */ - if(depth) - { ss.set_frames[depth].odatp->parent_odatp = ss.set_frames[depth-1].odatp; - if(ss.set_frames[depth-1].setp->num_sets < MAX_SETS) - ss.set_frames[depth-1].setp->set_list[ss.set_frames[depth-1].setp->num_sets++] = ss.set_frames[depth].setp; - else - { printf("you have allocated too many sets in insert_namelist()\n"); - //TODO: EXIT() - } - } - else /* no parent set, so assign to cdat set_list */ - { ss.set_frames[depth].odatp->parent_odatp = NULL; //no parent odat = NULL. - if(curr_cdat_set()->num_sets < MAX_SETS) - curr_cdat_set()->set_list[curr_cdat_set()->num_sets++] = ss.set_frames[depth].setp; - else - { printf("you have allocated too many sets in insert_namelist()\n"); - //TODO: EXIT() - } - } - - - ss.set_frames[depth].num_names = set_numnames; - ss.curr_depth = depth; - } - - } - + iter->nextsib = struct_alloc(ir_set_t); + struct_clear(iter->nextsib); + iter->nextsib->name = name_alloc(name); + return iter->nextsib; +} + +/* Add a framebox to a set + Attempts to create a new framebox of the specified set, returning + the framebox if it already exists + Name is not allocated, but assigned, unlike other "XXX_add" functions where + name is duplicated into IR's internal array. +*/ +static inline +struct ir_framebox_t* ir_set_add_framebox +( struct ir_set_t* set, + uint8_t* name +) +{ struct ir_framebox_t* iter; + if (set->frameboxes == NULL) + { set->frameboxes = struct_alloc(ir_framebox_t); + struct_clear(set->frameboxes); + set->frameboxes->header.data_name = name; + return set->frameboxes; } - done: - ; -} - -/*. We create new odats for each map variant that are children of the current odat/set - , set their name as the map name, and identify them by marking them as a map. This lets - us distinguish between sibling odatsthat have the same name because the map of the parent - odat had the same name as another, regular odat*/ -#define CURR_SS_FRAME() (ss.set_frames[ss.curr_depth]) -#define CURR_SS_SETP() (CURR_SS_FRAME().setp) -#define CURR_SS_ODATP() (CURR_SS_FRAME().odatp) -void -insert_map -( name, direction, height, width, refid, filepath ) - struct name* name; - int direction, height, width, refid; - uint8_t* filepath; -{ int i; - struct odat* curr_mem_odatp; //pointer to odat in odat_buf - struct set* curr_mem_setp; //pointer to set in set_buf - struct link* linkp; - - curr_mem_odatp = alloc_odat(); - curr_mem_setp = alloc_set(); - //Create a new odat, make its parent be the set. Make a set for mdat, its name should - //be the name of the odat + name of model. That makes a conflict beween odats that are named - //the same thing as the model of a sibling odat that was created from a map. They can have - //same name if the map odat is marked. So mark the map odat. - - //insert parent odat - curr_mem_odatp->parent_odatp = CURR_SS_ODATP(); - //insert into set_list - if(CURR_SS_SETP()->num_sets < MAX_SETS) - CURR_SS_SETP()->set_list[CURR_SS_SETP()->num_sets++] = curr_mem_setp; - else - { printf("You have allocated to many sets, error in insert_map()\n"); - //TODO: EXIT() + iter = set->frameboxes; + check: + if (bytes_identical(iter->header.data_name, name)) + return iter; + if (iter->header.nextsib != NULL) + { iter = (struct ir_framebox_t*) iter->header.nextsib; + goto check; } - - //indicate that newly created odat is a map - curr_mem_odatp->ismap = 1; - //set odat and set name - name_u8_cpy(&curr_mem_odatp->name, name); - - /* set cdat idx values for both set and odat */ - curr_mem_setp->cdat_idx = num_cdats; - - - /* Generate refid if needed, put into ref_buf */ - if(!refid) - refid = ss_refid++; - - insert_ref(curr_mem_odatp, refid); - - /* If current odatp on stack has a link, then we need to make our own link. just set the vdat_idx */ - if(CURR_SS_ODATP()->vdat_idx = 0) - { //alloc a link - linkp = alloc_link(); - linkp->type = CURR_SS_ODATP()->linkp->type; - linkp->dest_odatp = CURR_SS_ODATP(); - linkp->dest_refid = refid; - linkp->link_t.mlink.src_refid = CURR_SS_ODATP()->linkp->link_t.mlink.src_refid; - - /* Copy the animation name of the vlink*/ - name_u8_cpy(&linkp->link_t.vlink.src_animname, &CURR_SS_ODATP()->linkp->link_t.vlink.src_animname); - /* Copy the namelist of the vlink*/ - for(i = 0; i < MAX_DEPTH; i++) - name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &CURR_SS_ODATP()->linkp->link_t.vlink.src_namelist[i]); + iter->header.nextsib = (union ir_setdata_t*) struct_alloc(ir_framebox_t); + struct_clear(iter->header.nextsib); + iter->header.nextsib->header.data_name = name; + return (struct ir_framebox_t*) (iter->header.nextsib); +} + +/* Match two null-terminated bytestrings + Return 1 if the two bytestrings are identical, else 0 +*/ +static inline +int bytes_identical +( const uint8_t* stra, + const uint8_t* strb +) +{ int ca, cb; + do { + ca = *stra++; + cb = *strb++; + } while (ca && ca != '_' && ca == cb); + return (ca == cb); +} + +static inline +int classnames_identical +( const uint8_t* stra, + const uint8_t* strb +) +{ int ca, cb; + do { + ca = *stra++; + cb = *strb++; + } while (ca && ca == cb); + return (ca == cb); +} + +/* Assign Setdata to Set */ +void ir_set_assign_data +( struct ir_set_t* set, + union ir_setdata_t* setdata +) +{ struct ir_framebox_t* framebox; + struct ir_simplex_t* simplex; + switch (setdata->header.type) + { case FSDAT: + framebox = ir_set_add_framebox(set, setdata->header.data_name); + if (framebox->framesheets[setdata->framesheet.frameinfo.facing].header.data_name != NULL) + wprintf("Duplicate framesheet [%i] %s\n", + setdata->framesheet.frameinfo.facing, setdata->header.data_name); + framebox->framesheets[setdata->framesheet.frameinfo.facing] = setdata->framesheet; + break; + case MSDAT: + framebox = ir_set_add_framebox(set, setdata->header.data_name); + if (framebox->mapsheets[setdata->mapsheet.frameinfo.facing].header.data_name != NULL) + wprintf("Duplicate mapsheet [%i] %s\n", + setdata->mapsheet.frameinfo.facing, setdata->header.data_name); + framebox->mapsheets[setdata->mapsheet.frameinfo.facing] = setdata->mapsheet; + break; + case ADAT: + if (set->audio == NULL) + { set->audio = (struct ir_simplex_t*) setdata; + return; + } + simplex = set->audio; + while (simplex->header.nextsib != NULL) + if (bytes_identical(simplex->header.data_name, setdata->header.data_name)) + { wprintf("Duplicate audio %s\n", setdata->header.data_name); + *simplex = setdata->audio; + //setdata is now a pointer to redundant, unused memory. + return; + } + else + simplex = (struct ir_simplex_t*) simplex->header.nextsib; + setdata->audio.header.nextsib = (union ir_setdata_t*) set->audio; + set->audio = (struct ir_simplex_t*) setdata; + break; + case LDAT: + setdata->link.header.nextsib = (union ir_setdata_t*) set->links; + set->links = (struct ir_link_t*) setdata; + break; + default: + fprintf(stderr, "Unknown setdata type %x\n", setdata->header.type); + exit(-1); } - else - curr_mem_odatp->vdat_idx = CURR_SS_ODATP()->vdat_idx; - - - - } - - -/* 11/22 Each vdat has a multiple models. Each model has 8 framesheets, one in each - direction, that create a spritesheet. Inserting framesheets into the correct - model is just a matter of checking whether or not the last models name matches - - the current one. We can never get a framesheet that is for the same model before - AND after some other model, due to alphasorting of the files in each directory */ -void -insert_framesheet -( model_name, direction, height, width, refid, filepath ) - struct name* model_name; - int direction, height, width, refid; - uint8_t* filepath; -{ struct vdat* curr_vdatp; - struct model* curr_modelp; - static struct name last_model_name[32]; - - - curr_vdatp = curr_vdat(); - - /* If the model name changed, that means there are no more - framesheets for that model to be processed, a guaruntee we make - b/c the filenames are alphabetically sorted */ - if(!name_u8_cmp(last_model_name, model_name)) - { if(curr_vdatp->num_models) - curr_vdatp->num_models++; - num_models++; // total number of models - } - - if(CURR_SS_ODATP()->refid == 0) - { if(!refid) - refid = ss_refid++; - insert_ref(CURR_SS_ODATP(), refid);//given a odatp and a refid, insert the odatp into the ref_buf. - //push ref into ref_buf. - } +void ir_set_assign_ref +( struct ir_set_t* set, + uint32_t ref +) +{ uint16_t hash, oldhash; + struct ir_set_t** iters; + struct pagenode_t* iterp; + uint32_t oldref; + oldref = set->ref; + oldhash = 0; + hash = REFHASH(ref); + iterp = refhashpages.root; + check_depth: + iters = ((struct ir_set_t**) iterp->root) + hash; + if (*iters == NULL || *iters == set) + *iters = set; else - printf("error: redefining a previously set refid\n"); - - curr_modelp = curr_model(); - - name_u8_cpy(&curr_modelp->name, model_name); - curr_modelp->spritesheet[direction].height = height; - curr_modelp->spritesheet[direction].width = width; - - name_u8_cpy(last_model_name, model_name); - - -} - - - -//src_path is stored in link_namelist -void -insert_mlink -( src_mapname, src_refid) - struct name* src_mapname; - int src_refid; -{ struct link* linkp; - int i; - - linkp = alloc_link(); - - /* set type */ - linkp->type = 3; - /* set the name of the src map for the link, if a name exists */ - if(src_mapname) - name_u8_cpy(&linkp->link_t.mlink.src_mapname, src_mapname); - /* Set the source ref id of the link */ - linkp->link_t.mlink.src_refid = src_refid; - /* Copy the entire namelist of the link, if it exists */ - for(i = 0; i < link_numnames; i--) //TODO MAX_DEPTH -> link_namelist_num?? - { name_u8_cpy(&linkp->link_t.mlink.src_namelist[i], &link_namelist[i]); - name_u8_set(&link_namelist[i], (ucs4_t) 0); + { if (iterp->header.next == NULL) + pagelist_alloc(refhashpages); + iterp = iterp->header.next; + goto check_depth; } - link_numnames = 0; - - linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack - -} - -void -insert_link_name -( name ) - struct name* name; -{ - //Push name onto current namelist, set the set_namelist. - name_u8_cpy(&link_namelist[link_numnames++], name); - -} - -/* Nearly identical to mlink */ -void -insert_vlink -( src_animname, src_refid ) - struct name* src_animname; - int src_refid; -{ struct link* linkp; - int i; - - linkp = alloc_link(); - - /* set type */ - linkp->type = 2; - - /* set the name of the src animname for the link, if a name exists */ - if(src_animname) - name_u8_cpy(&linkp->link_t.vlink.src_animname, src_animname); - - /* Set the source ref id of the link */ - linkp->link_t.mlink.src_refid = src_refid; - - /* Copy the entire namelist of the link, if it exists */ - for(i = 0; i < link_numnames; i++) //TODO MAX_DEPTH -> link_namelist_num?? - { name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &link_namelist[i]); - name_u8_set(&link_namelist[i], (ucs4_t) 0);//set to null for next link_namelist - } - - linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack - -} - - -/* TODO: Do we really need to store the prev/next pointer? iterating through the - ref_buf could be achieved by iterating until the num_refs anyway. */ -void -insert_ref -( odatp, refid ) - struct odat* odatp; - int refid; -{ struct ref* curr_refp; - struct ref* prev_refp; - - curr_refp = alloc_ref(); - prev_refp = prev_ref(); - - prev_refp->nextref = curr_refp; - curr_refp->lastref = prev_refp; - - curr_refp->odatp = odatp; - curr_refp->refid = refid; - - if(refid % 16) - { POST_ALLOC(); - CURRENT_POST()->refid = refid; - CURRENT_POST()->odatp = odatp; + if (oldref != 0) + { wprintf("Ref override: 0x%x -> 0x%x for set %s\n", oldref, ref, set->name); + if (oldhash != 0) + *iters = NULL; + else + { oldhash = hash; + hash = REFHASH(oldref); + goto check_depth; + } } - - - -} - -void -insert_vdat -() -{ struct odat* curr_ss_odatp; - struct vdat* curr_vdatp; - - curr_vdatp->creator = curr_ss_odatp; - curr_ss_odatp->vdat_idx = num_vdats; - curr_ss_odatp->vdatp = curr_vdatp; - alloc_vdat(); + set->ref = ref; } -void -insert_refid_statement -( refid ) - int refid; -{ CURR_SS_ODATP()->refid = refid; -} -#if 0 - - -/* 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, 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. Curr set points the sets representation in the cdat, curr_set_odatp - points to the sets representation as an odat*/ - -//TODO: Add insert_set_ref() -//TODO: Is this the correct allocation scheme? No do the one ken suggested -void -insert_s_name -( struct name* name +void ir_data_assign_path +( union ir_setdata_t* setdata, + const uint8_t* path ) -{ - - struct set* curr_setp; - - curr_setp = curr_set(); - curr_set_odatp = alloc_odat(); - - u8_cpy(curr_set_odatp->name, name, 32); - u8_cpy(curr_setp->name, name, 32); - curr_set_odatp->parent_odatp = NULL; - - -} - -/* Inserting a olink instead of a set. Set is really just a placeholder - for another set. Allocate the memory for the set so taht it can be populated*/ -void -insert_set_olink -( int refid +{ if (path == NULL) + eprintf("Null path in data %s\n", setdata->header.data_name); + if (setdata->header.src_filename != NULL) + wprintf("Path override: %s -> %s for setdata %s\n", + setdata->header.src_filename, path, setdata->header.data_name); + setdata->header.src_filename = name_alloc(path); +} + +union ir_setdata_t* ir_framesheet +( const uint8_t* name, + apc_facing d, + int width, + int height ) -{ - struct set* curr_setp; +{ return ir_framedata(FSDAT, name, d, width, height); } - curr_setp = curr_set(); - - curr_setp->refid = refid; - -} - -void -insert_set_vlink -( int refid, - uint8_t* anim_name +union ir_setdata_t* ir_mapsheet +( const uint8_t* name, + apc_facing d, + int width, + int height ) -{ - struct cdat* curr_cdatp; - struct odat* curr_odatp; - struct link* curr_linkp; - - - curr_cdatp = curr_cdat(); - curr_odatp = curr_odat(); - curr_linkp = alloc_link(); - - /* Insert vlink into link_stack so that it gets processed at - output time */ - curr_linkp->type = 2; - /* Store the target odat information*/ - curr_linkp->link_t.vlink.refid = refid; - u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32); - /* Store the linking odat/cdat information */ - curr_linkp->classp = curr_cdatp; - curr_linkp->odatp = curr_odatp; - curr_linkp->set_idx = curr_cdatp->num_sets; - // curr_linkp->ele_idx = -1; - -} - -/* Svlinks dont have animation names */ -void -insert_set_svlink -( int refid +{ return ir_framedata(MSDAT, name, d, width, height); } + +static inline +union ir_setdata_t* ir_framedata +( enum dtype type, + const uint8_t* name, + apc_facing d, + int width, + int height ) -{ - struct cdat* curr_cdatp; - struct link* curr_linkp; - - curr_cdatp = curr_cdat(); - curr_linkp = alloc_link(); - - /* Insert svlink into link_stack so that it gets processed at - output time */ - curr_linkp->type = 3; - curr_linkp->classp = curr_cdatp; - curr_linkp->set_idx = curr_cdatp->num_sets; - // curr_linkp->ele_idx = -1; - curr_linkp->link_t.svlink.refid = refid; - -} - -/* 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 -() -{ int refid; - struct odat* curr_odatp; - struct cdat* curr_cdatp; - struct set* curr_setp; - struct ref* prev_refp; - struct ref* curr_refp; - struct vdat* curr_vdatp; - - curr_odatp = curr_set_odatp; //allocated at insert_set_label - curr_cdatp = curr_cdat(); - curr_setp = curr_set(); - prev_refp = curr_ref(); - curr_refp = alloc_ref(); - curr_vdatp = curr_vdat(); - - curr_vdatp->creator = curr_set_odatp; - - curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx? - u8_cpy(curr_setp->name, curr_odatp->name, 32); - curr_cdatp->num_sets++; - - curr_odatp->cdat_idx = curr_cdatp->idx; - curr_odatp->refp = curr_refp; - - refid = curr_setp->refid; // refid set by insert_set_label(name, refid) - - curr_refp->refid = refid; - 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_set_vdatid -() -{ - struct vdat* curr_vdatp; - - curr_vdatp = curr_vdat(); - - curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks - curr_set_odatp->vdatp = curr_vdatp; - curr_set_odatp = NULL; //This sets odat shouldnt be modified after populating odats vdat info -} - -/* Populates the odat name and refid for odat, allocate the odat here for the rest of - the functions to use via curr_odat(). */ -void -insert_ele_label -( uint8_t* name, - int refid +{ struct ir_framedata_t* framedata = struct_alloc(ir_framedata_t); + struct_clear(framedata); + if (name == NULL) + eprintf("Null name in set allocation\n"); + framedata->header.type = type; + framedata->header.data_name = name_alloc(name); + framedata->frameinfo.facing = d; + framedata->frameinfo.w = width; + framedata->frameinfo.h = height; + return (union ir_setdata_t*) framedata; +} + +union ir_setdata_t* ir_audio +( const uint8_t* name ) +{ struct ir_simplex_t* audio = struct_alloc(ir_simplex_t); + struct_clear(audio); + if (name == NULL) + eprintf("Null audio\n"); + audio->header.type = ADAT; + audio->header.data_name = name_alloc(name); + return (union ir_setdata_t*) audio; +} + + +/* Create classld that points to a class */ +struct ir_classld_t* ir_classld_from_class +( struct ir_class_t* class ) +{ struct ir_classld_t* classld; + if (class == NULL) + eprintf("Null class in classld\n"); + classld = struct_alloc(ir_classld_t); + struct_clear(classld); + classld->root_class = class; + return classld; +} + +struct ir_setld_t* ir_setld_from_ref +( uint32_t ref ) +{ struct ir_setld_t* setld; + setld = struct_alloc(ir_setld_t); + struct_clear(setld); + setld->ref = ref; + return setld; +} + +struct ir_setld_t* ir_setld_from_classld +( struct ir_classld_t* classld, + const uint8_t* name ) -{ - struct odat* curr_odatp; - - curr_odatp = alloc_odat(); - - u8_cpy(curr_odatp->name, name, 32); - curr_odatp->map[0] = 0; - - if(refid != -1) - curr_odatp->refid = refid; +{ struct ir_setld_t* setld; + setld = struct_alloc(ir_setld_t); + struct_clear(setld); + setld->namelist = struct_alloc(ir_namelist_t); + struct_clear(setld->namelist); + setld->namelist_head = setld->namelist; + setld->namelist_head->name = name_alloc(name); + setld->classld = classld; + return setld; +} + +struct ir_setld_t* ir_setld_addchild +( struct ir_setld_t* setld, + const uint8_t* name +) +{ if (setld->namelist == NULL) + { setld->namelist = struct_alloc(ir_namelist_t); + struct_clear(setld->namelist); + setld->namelist_head = setld->namelist; + } else - curr_odatp->refid = ss_refid++; - + { setld->namelist_head->nextsib = struct_alloc(ir_namelist_t); + struct_clear(setld->namelist_head->nextsib); + setld->namelist_head = setld->namelist_head->nextsib; + } + setld->namelist_head->name = name_alloc(name); + return setld; } -/* We don't make an odat here, at output time we will resolve - the refid to the corresponding odat. */ -void -insert_ele_olink -( int refid +union ir_setdata_t* ir_link +( enum ltype link_type, + struct ir_setld_t* setld, + const uint8_t* name ) -{ - /* Do nothing because we already know the refid that - the odat needs for this element (in the quad_file) */ -} - -void -insert_ele_vlink -( int refid, - uint8_t* anim_name +{ struct ir_link_t* link; + link = struct_alloc(ir_link_t); + struct_clear(link); + link->header.type = LDAT; + link->type = link_type; + link->classld = setld->classld; + link->setld = setld; + if (link_type != OLINK && name != NULL) + link->header.data_name = name_alloc(name); + return (union ir_setdata_t*) link; +} + +static inline +void* pagelist_pop +( struct pagelist_t* pagelist, + size_t size ) -{ - 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_linkp->classp = curr_cdatp; - 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.refid = refid; - u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32); - +{ size_t headsize = PL_HEADSIZE((*pagelist)); + if (!headsize) + { free(pagelist->head); + pagelist->head = pagelist->root; + while (pagelist->head->header.next != NULL) + pagelist->head = pagelist->head->header.next; + } + if (headsize < size) + eprintf("Attempted to pop unaligned value from pagelist\n"); + pagelist->head->header.head -= size; + return pagelist->head->header.head; +} + +static +void* stack_alloc +( size_t bytes ) +{ void* p; + if (PL_HEADMEM(datapages) < bytes) + pagelist_alloc(datapages); + p = datapages.head->header.head; + datapages.head->header.head += bytes; + return p; +} + +static +uint8_t* name_alloc +( const uint8_t* name_src ) +{ const uint8_t* iter; + uint8_t* name; + int head_mem; + copy: + name = (uint8_t*)namepages.head->header.head; + iter = name_src; + for (head_mem = PL_HEADMEM(namepages); *iter && *iter != '_' && *iter != '.' && head_mem; head_mem--) + *(namepages.head->header.head)++ = *iter++; + if (head_mem < 1) //not enough room + { pagelist_alloc(namepages); + goto copy; + } + *(namepages.head->header.head)++ = '\0'; + return name; +} + +static +uint8_t* classname_alloc +( const uint8_t* name_src ) +{ const uint8_t* iter; + uint8_t* name; + int head_mem; + copy: + name = (uint8_t*)namepages.head->header.head; + iter = name_src; + for (head_mem = PL_HEADMEM(namepages); *iter && head_mem; head_mem--) + *(namepages.head->header.head)++ = *iter++; + if (head_mem < 1) //not enough room + { pagelist_alloc(namepages); + goto copy; + } + *(namepages.head->header.head)++ = '\0'; + return name; +} + +static void crawl_class(struct ir_class_t*); +static void crawl_set(struct ir_set_t*,int); +void ir_test(void) +{ uprintf("IR From Directory: %s\n",getcwd(NULL,255)); + crawl_class(&root_class); + if (root_class.root_set != NULL) + crawl_set(root_class.root_set, 0); +} + +static +void crawl_class +( struct ir_class_t* class ) +{ struct ir_class_t* iter; + for (iter = class->nextchild; iter != NULL; iter = iter->nextsib) + { wprintf("%U/\n", iter->name); + if(chdir((char*)iter->name)) + eprintf("CHDIR %U from %s\n",iter->name,getcwd(NULL,255)); + crawl_class(iter); + if (iter->root_set != NULL) + crawl_set(iter->root_set, 0); + uprintf("%U\\\n",iter->name); + if (chdir("..")) + eprintf("CHDIR ..\n"); + } } -void -insert_ele_svlink -( int refid +static +void crawl_set +( struct ir_set_t* set, + int depth ) -{ - 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_linkp->classp = curr_cdatp; - curr_linkp->type = 3; - - //curr_linkp->ele_idx = curr_setp->num_ele; - curr_linkp->link_t.svlink.refid = refid; - - -} - -//Insert element into odat_buf and cdatpages -void -insert_ele() -{ - int refid; - struct cdat* curr_cdatp; - struct odat* curr_odatp; - struct vdat* curr_vdatp; - struct set* curr_setp; - struct ele* curr_elep; - struct ref* curr_refp; - struct ref* prev_refp; - - - curr_odatp = curr_odat(); //malloced @ insert_ele_label - curr_vdatp = curr_vdat(); - curr_setp = curr_set(); - prev_refp = curr_ref(); - curr_refp = alloc_ref(); - - curr_vdatp->creator = curr_odatp; - - /* Populate odat for ele */ - curr_odatp->cdat_idx = curr_cdatp->idx; - curr_odatp->refp = curr_refp; - curr_odatp->parent_odatp = curr_set_odatp; - - refid = curr_odatp->refid; - - curr_refp->refid = refid; - curr_refp->lastref = prev_refp; - curr_refp->odatp = curr_odatp; - prev_refp->nextref = curr_refp; - -} - -void -insert_ele_vdatid -() -{ struct odat* curr_odatp; - curr_odatp = curr_odat(); - curr_odatp->vdat_id = num_vdats; +{ struct ir_set_t* setlist[64], ** slp, * iter; + int i = depth * 12; + while (i--) + putchar('.'); + i = depth; + slp = setlist; + for(iter = set; iter != NULL; iter = iter->nextchild) + { uprintf("[%10U]", iter->name); + *slp++ = iter; + i++; + } + --i; + putchar('\n'); + for(iter = *--slp; slp >= setlist; iter = *--slp, --i) + if (iter->nextsib != NULL) + crawl_set(iter->nextsib,i); } - - - -#endif - - - - -/* void */ -/* insert_quad */ -/* ( int x, int y, int z, int refid */ -/* ) */ -/* { */ -/* struct quad* curr_quadp; */ - -/* curr_quadp = curr_quad(); */ - -/* curr_quadp->x = x; */ -/* curr_quadp->y = y; */ -/* curr_quadp->z = z; */ -/* curr_quadp->refid = refid; */ - - - -/* } */ - -/* /\* serting the hitbox into the set */ -/* odat. Elements that don't have */ -/* a hitbox will use the sets root. *\/ */ -/* void */ -/* insert_hitbox */ -/* ( int hitbox */ -/* ) */ -/* { struct odat* curr_odatp; */ - -/* curr_odatp = curr_odat(); */ -/* curr_odatp->hitbox = hitbox; */ -/* } */ - -/* /\* 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 odat* curr_odatp; */ - -/* curr_odatp = curr_odat(); */ -/* curr_odatp->root.x = x; */ -/* curr_odatp->root.y = y; */ -/* curr_odatp->root.z = z; */ -/* } */ - - - - -/* void */ -/* insert_frame_pointer */ -/* ( uint8_t direction, */ -/* void* frame */ -/* ) */ -/* { struct model* curr_modelp; */ - -/* curr_modelp = curr_model(); */ - -/* curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */ -/* } */ -