X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fir.c;h=63fe72bbdfa353ceea2324c3da81779f8d880ef5;hp=432581393f98eba20912c39ed53d791b334420f2;hb=1f5e543b9088b021c859a2995a273dfa3397d381;hpb=55eb5697b20b577ecb4a3c6355c1ee4695f016cd diff --git a/src/ir.c b/src/ir.c index 4325813..63fe72b 100644 --- a/src/ir.c +++ b/src/ir.c @@ -4,915 +4,399 @@ \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 +/* Local */ #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(void); -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_refid(int); -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]) - - - - -/* 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" +/* Public */ +int ir_init(void); +void ir_quit(void); +int ir_linker(void); +int ir_condenser(void); +/* Private */ +struct pagenode_t; +extern //apc.c +long sys_pagesize; +static inline +struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*, uint8_t*); +static +void ir_free_pages(struct pagenode_t*); +static inline +int bytes_identical(uint8_t*,uint8_t*); +static +void* stack_alloc(size_t); +/* Memory allocator */ +struct pagenode_t { + struct pagenode_t* next; + char* head; + char root[]; +}* pagenode_root, * pagenode_head; +#define PN_ALLOCSIZE (sys_pagesize) +#define PN_HEADERSIZE() (sizeof(struct pagenode_t*) + sizeof(char*)) +#define PN_MEMSIZE() (PN_ALLOCSIZE - PN_HEADERSIZE()) +#define PN_HEADSIZE() (pagenode_head->head - pagenode_head->root) +#define PN_HEADSPACE() (PN_MEMSIZE() - PN_HEADSIZE()) +/* Enumerated types */ +enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; +enum ltype { OLINK, MLINK, VLINK, ALINK }; +/* Set data mem */ +struct ir_setdata_header_t +{ enum dtype type; + uint8_t* src_filename, * data_name; + union ir_setdata_t* nextsib; }; - - -struct set { - int cdat_idx; - int num_sets; - struct set* set_list[MAX_SETS]; +struct ir_frameinfo_t +{ int facing, w, h; }; +struct ir_framedata_t +{ struct ir_setdata_header_t header; + struct ir_frameinfo_t frameinfo; }; - -struct ref { - struct ref* nextref; - struct ref* lastref; - struct odat* odatp; - int refid; //0xFFFFFF->digit +struct ir_framebox_t +{ struct ir_setdata_header_t header; + struct ir_framedata_t framesheets[FACING_MAX]; + struct ir_framedata_t mapsheets[FACING_MAX]; }; - -struct olink { - int src_refid; +struct ir_simplex_t +{ struct ir_setdata_header_t header; }; +struct ir_link_t +{ struct ir_setdata_header_t header; + struct ir_set_t* src, * trg; + enum ltype type; }; - -struct vlink { - int src_refid; - struct name src_animname; - struct name src_namelist[MAX_DEPTH]; +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; }; - -struct mlink { - int src_refid; - struct name src_mapname; - struct name src_namelist[MAX_DEPTH]; - -}; - -union link_t { - struct vlink vlink; - struct mlink mlink; - struct olink olink; -}; - - -/* Links are a mechanism for designers to indicate in the grammar that a odat, vdat, or map - is defined elsewhere and that the link should be replaced with the specified odat/vdat/map */ -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 map { - struct name name; - int height; - int width; - uint8_t filepath[FPATH_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; /* null if parent is a cdat */ - struct ref* refp; /* pointer to it's ref on ref_list */ - struct map map; /* only valid if odat ismap */ - -}; - -/* A framesheet is a grouping of animation frames in a single direction (N,W,S,E, etc.). Framesheets - also hold the framesheet dimensions and the filepath to the png of the framesheet so the file can be opened - and the png data can be extracted. */ -struct framesheet { - int width; - int height; - uint8_t filepath[FPATH_MAX]; - int num_frames; - +struct ir_class_t +{ struct ir_class_t* nextchild, * nextsib; + struct ir_set_t* root_set; + uint8_t* name; }; - -/* A model is a collection of framesheets for every - direction (N,W,S,E,NW,NE,SW,SE). Currently, users can only define - framesheets in the APC grammar, which are inserted into the current model*/ -struct model { - struct name name; - struct framesheet spritesheet[8]; //one for each -}; - -/* Vdat: Vdats are the video data of each object. 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]; -}; - -/* An entry on the set_stack that describes the namelist and relevant information for - the current set that is being processed in the parser. For each set name, - there is a corresponding set/odat that is created when set names are encountered. */ - -struct set_frame -{ struct name namelist[MAX_DEPTH]; - int num_names; - struct set* setp; - struct odat* odatp; -} ; - -/* Stores the last defined set at every depth */ -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 +struct ir_set_t +{ struct ir_set_t* nextchild, * nextsib; + struct ir_class_t* class; + long long ref; + uint8_t* name; + struct ir_framebox_t* frameboxes; + struct ir_simplex_t* audio; + struct ir_link_t* links; }; - - -//"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); - - 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(); - - +/* Function-Like Macros */ +#define do_warn() do { \ + } while (0) +#define wprint(str) do { \ + fprintf(stderr, str); \ + do_warn(); \ + } while (0) + #define wprintf(fmt,...) do { \ + fprintf(stderr, fmt, __VA_ARGS__); \ + do_warn(); \ + } while (0) +#define do_error() do { \ + exit(-1); \ + } while (0) +#define eprint(str) do { \ + fprintf(stderr, str); \ + do_error(); \ + } while (0) +#define eprintf(fmt,...) do { \ + fprintf(stderr, fmt, __VA_ARGS__); \ + do_error(); \ + } while (0) +#define struct_alloc(_T) ((struct _T*) stack_alloc(sizeof(struct _T))) + +static +struct ir_class_t root_class = { .name = (uint8_t*)"." }; + +/* Init */ +int ir_init +( void ) +{ pagenode_root = (struct pagenode_t*) calloc((size_t)PN_ALLOCSIZE,1); + if (pagenode_root == NULL) + return -1; + pagenode_root->head = pagenode_root->root; + pagenode_head = pagenode_root; 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]); - } - -} - -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(); -} - -//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(); - - +} + +/* Quit/Cleanup + Recursively clean pagenode linked list +*/ +void ir_quit +( void ) +{ ir_free_pages(pagenode_root); } + +static +void ir_free_pages +( struct pagenode_t* pagenode ) +{ if (pagenode->next != NULL) + ir_free_pages(pagenode->next); + free(pagenode); } -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); +/* Link +*/ +int ir_linker +( void ) +{ return 0; } + +/* Condense +*/ +int ir_condenser +( void ) +{ return 0; } + +/* 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, + uint8_t* name +) +{ struct ir_class_t* iter; + if (class->nextchild == NULL) + return class->nextchild = struct_alloc(ir_class_t); + iter = class->nextchild; + check: + if (bytes_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - else - SET_ALLOC(); - - return CURRENT_SET(); + return iter->nextsib = struct_alloc(ir_class_t); } - -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); +/* 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, + uint8_t* name +) +{ struct ir_set_t* iter; + if (class->root_set == NULL) + return class->root_set = struct_alloc(ir_set_t); + iter = class->root_set; + check: + if (bytes_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - else - LDAT_ALLOC(); - - return CURRENT_LINK(); - + return iter->nextsib = struct_alloc(ir_set_t); } -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); +/* 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, + uint8_t* name +) +{ struct ir_set_t* iter; + if (set->nextchild == NULL) + return set->nextchild = struct_alloc(ir_set_t); + iter = set->nextchild; + check: + if (bytes_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - else - REF_ALLOC(); - - - if(num_refs % 16 == 0) - { CURRENT_POST() = CURRENT_REF(); - inc_posts(); - } - - return CURRENT_REF(); + return iter->nextsib = struct_alloc(ir_set_t); } -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); +/* Add a framebox to a set + Attempts to create a new framebox of the specified set, returning + the framebox if it already exists +*/ +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) + return set->frameboxes = struct_alloc(ir_framebox_t); + 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; } - else - POST_ALLOC(); - -} - -struct cdat* -curr_cdat -() -{ - return (*cdat_stackp); -} - -struct odat* -curr_odat -() -{ - return CURRENT_ODAT(); + iter->header.nextsib = (union ir_setdata_t*) struct_alloc(ir_framebox_t); + return (struct ir_framebox_t*) iter->header.nextsib; } -struct vdat* -curr_vdat -() -{ - return CURRENT_VDAT(); -} -struct set* -curr_cdat_set -() -{ - return CURRENT_SET(); -} - -struct ref* -curr_ref -() -{ - return CURRENT_REF(); -} -struct ref* -prev_ref -() -{ - return PREVIOUS_REF(); -} -struct model* -curr_model -() -{ - return &CURRENT_MODEL(); +/* Match two null-terminated bytestrings + Return 1 if the two bytestrings are identical, else 0 +*/ +static inline +int bytes_identical +( uint8_t* stra, + uint8_t* strb +) +{ while (*stra && *strb) + if (*stra++ != *strb++) + return 0; + return *stra == *strb; } -/* IR.C*/ -void -push_cdat -( 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 -( struct name* name ) -{ - //Push name onto current namelist, set the set_namelist. - name_u8_cpy(&set_namelist[set_numnames++], name); - -} - - -/* Called at the last name of a sets namelist. Inserts the set namelist - onto the set_stack at the appropriate depth i.e. the number of names in - the namelist. If each name in the namelist at every depth matches, nothing happens. For every - name on the namelist that doesnt match what is currently on the set_stack, - a new set/odat is created at the depth that it describes. E.g. a set name - of A_B_C is a depth of 3 and is represented in the set_stack as A, A_B and A_B_C. - If a new set namelist is defined, X_Y, the new set_stack will become X, X_Y. */ - -void -insert_set_namelist -( struct name* name ) -{ int depth, nameidx, i; - - insert_set_name(name); - - - 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; - - /* Every set has a vdat, but some won't be populated because the namelist that instantiated */ - /* the set might not have a SS statement that populates the models of the vdat. This is ok */ - /* because 1) IR is supposed to be bloated so that binary out isnt 2) this functionality */ - /* preserves the assumptions that insert_framesheet() makes when it calls curr_vdat() */ - alloc_vdat(); +/* 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; + struct ir_link_t* link; + 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->audio is now a pointer to redundant, unused memory. + return; } - - } - + else + simplex = (struct ir_simplex_t*) simplex->header.nextsib; + simplex->header.nextsib = setdata; + break; + case LDAT: + if (set->links == NULL) + { set->links = (struct ir_link_t*) setdata; + return; + } + link = set->links; + while (link->header.nextsib != NULL) + link = (struct ir_link_t*) link->header.nextsib; + link->header.nextsib = setdata; + break; + default: + fprintf(stderr, "Unknown setdata type %x\n", setdata->header.type); + exit(-1); } - - /* Set to 0 to reset for next set_namelist */ - set_numnames = 0; } - -/* 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 odats that 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 -( struct name* name, int direction, int height, int width, int refid, uint8_t* filepath ) -{ int i; - struct odat* curr_map_odatp; //pointer to odat in odat_buf - struct set* curr_map_setp; //pointer to set in set_buf - struct link* linkp; - - curr_map_odatp = alloc_odat(); - curr_map_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_map_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_map_setp; - else - { printf("You have allocated to many sets, error in insert_map()\n"); - //TODO: EXIT() - } - - /* indicate that newly created odat is a map */ - curr_map_odatp->ismap = 1; - /* set odat and set name */ - name_u8_cpy(&curr_map_odatp->name, name); - - /* set cdat idx values for both set and odat */ - curr_map_setp->cdat_idx = num_cdats; - - /* Insert map information into the odats map */ - curr_map_odatp->map.height = height; - curr_map_odatp->map.width = width; - u8_stpncpy(curr_map_odatp->map.filepath, filepath, FPATH_MAX); - - - /* Generate refid if needed, put into ref_buf */ - if(!refid) - refid = ss_refid++; - - insert_ref(curr_map_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) - { 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]); - } - else - curr_map_odatp->vdat_idx = CURR_SS_ODATP()->vdat_idx; - +void ir_set_assign_ref +( struct ir_set_t* set, + long long ref +) +{ if (set->ref != 0) + wprintf("Ref override: 0x%lx -> 0x%lx for set %s\n", + (long unsigned) set->ref, (long unsigned) ref, set->name); + set->ref = ref; + //TODO: reflist_add(set); } - - -/* 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 -( struct name* model_name, int direction, int height, int width, int 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. */ - } - 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; - u8_stpncpy(curr_modelp->spritesheet[direction].filepath, filepath, FPATH_MAX); - name_u8_cpy(last_model_name, model_name); - +void ir_data_assign_path +( union ir_setdata_t* setdata, + uint8_t* path +) +{ setdata->header.src_filename = path; + //TODO: internal strdup, not assign (= path;) } -void -insert_mlink -( 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--) - { name_u8_cpy(&linkp->link_t.mlink.src_namelist[i], &link_namelist[i]); - name_u8_set(&link_namelist[i], (ucs4_t) 0); - } - link_numnames = 0; - - linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack - +//TODO: Macro ir_framsheet and mapsheet? +union ir_setdata_t* ir_framesheet +( uint8_t* name, + apc_facing d, + int width, + int height +) +{ struct ir_framedata_t* framesheet = struct_alloc(ir_framedata_t); + framesheet->header.type = FSDAT; + framesheet->header.data_name = name; + framesheet->frameinfo.facing = d; + framesheet->frameinfo.w = width; + framesheet->frameinfo.h = height; + return (union ir_setdata_t*) framesheet; } - -void -insert_link_name -( struct name* name ) -{ - //Push name onto current namelist, set the set_namelist. - name_u8_cpy(&link_namelist[link_numnames++], name); - +union ir_setdata_t* ir_mapsheet +( uint8_t* name, + apc_facing d, + int width, + int height +) +{ struct ir_framedata_t* mapsheet = struct_alloc(ir_framedata_t); + mapsheet->header.type = MSDAT; + mapsheet->header.data_name = name; + mapsheet->frameinfo.facing = d; + mapsheet->frameinfo.w = width; + mapsheet->frameinfo.h = height; + return (union ir_setdata_t*) mapsheet; } - -/* Nearly identical to mlink */ -void -insert_vlink -( 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++) - { 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 - } - link_numnames = 0; - - linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack - +union ir_setdata_t* ir_audio +( uint8_t* name ) +{ struct ir_simplex_t* audio = struct_alloc(ir_simplex_t); + audio->header.type = ADAT; + audio->header.data_name = name; + return (union ir_setdata_t*) audio; } - -/* 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 -( 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; +static +void* stack_alloc(size_t bytes) +{ if (!bytes) + { wprint("Attempting to allocate 0 bytes in stack_alloc"); + return pagenode_head->head; } - -} - - -void -insert_refid -( int refid ) -{ CURR_SS_ODATP()->refid = refid; + if (PN_HEADSPACE() < bytes) + { pagenode_head->next = (struct pagenode_t*) calloc(PN_ALLOCSIZE,1); + pagenode_head = pagenode_head->next; + pagenode_head->head = pagenode_head->root; + } + pagenode_head->head += bytes; + return (void*) pagenode_head->head - bytes; } - -void -insert_vdat -() -{ struct vdat* curr_vdatp; - - curr_vdatp = curr_vdat(); - - curr_vdatp->creator = CURR_SS_ODATP(); - CURR_SS_ODATP()->vdat_idx = num_vdats; - CURR_SS_ODATP()->vdatp = curr_vdatp; - alloc_vdat(); -}