X-Git-Url: https://git.kengrimes.com/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fbinaryout.c;h=f4eea8aa3bd2265b3d034838b044560f94a7adf3;hp=94f8c29f937930e8f05d1d83a517e8c0f0e57e14;hb=52b3767316142be128199f8f3a5eccd51d464d08;hpb=e4ad1c1a9499babb6804823e60377a14b6a0b583 diff --git a/src/binaryout.c b/src/binaryout.c index 94f8c29..f4eea8a 100644 --- a/src/binaryout.c +++ b/src/binaryout.c @@ -29,7 +29,7 @@ void ir_binout_init(struct ir_class_t*); /* Memory Allocation */ #define struct_alloc(_T) ((struct _T*) stack_alloc(&datapages, sizeof(struct _T))) static -struct pagelist_t linkpages, datapages; +struct pagelist_t linkpages, datapages, plinkpages; enum model_type { SS }; /* Binaryout out structure definitions */ @@ -73,12 +73,7 @@ struct bin_frame_header_t { int frames; long op_start; }; -struct bin_plink_t { - enum ltype type; - ir_set trg_set; - uint8_t* name; - long src_pos; -}; + struct bin_pixel_t { int x, y, z; uint32_t ref; @@ -109,18 +104,15 @@ struct bin_attachment_list_t **attachment_stack, **asp; //attachment_stack, atta FILE* binaryout; - #define NAMEHASH(name, domain) (XXH32(name, u8_strlen(name), 0XCEED ) & domain) static inline int bin_set_varcount ( ir_set set ) { int count; - framebox set_fb; framebox iter; - set_fb = ir_set_framebox(set); count = 0; - for (iter = set_fb; iter != NULL; iter = ir_setdata_nextsib(iter)) + for (iter = ir_set_framebox(set); iter != NULL; iter = ir_setdata_nextsib(iter)) count++; return count; } @@ -176,6 +168,9 @@ int bin_keys_identical return 0; } + +typedef RGBA_t uint32_t; + long bin_traverse_class(ir_class); /* Takes root class and begins processing */ void @@ -198,7 +193,7 @@ ir_binout_init(ir_class root_class) if(fseek(binaryout, entry_pos, SEEK_SET) == -1) eprintf("fseek failed with %s", strerror(errno)); \ } while (0) #define HT_END(_HTEND) (entry_pos >= _HTEND) //just in case at last entry -void +long /* TODO: Should overwrite be a default? */ bin_insert_ht_entry ( long ht_start, @@ -230,6 +225,8 @@ bin_insert_ht_entry INC_ENTRY(); } WRITE_ENTRY(); + + return entry_pos; } @@ -364,6 +361,12 @@ bin_traverse_set } /* | sdat header | + |------------------| + | num dlinks | + |------------------| + | dlink len | + |------------------| + | dlink string | |------------------| | variant ht | |------------------| @@ -375,10 +378,11 @@ bin_traverse_set */ -void bin_insert_links(int, struct bin_ht_header_t*, long); +void bin_insert_links(struct bin_processed_lists_t*, struct bin_ht_header_t*, long); struct bin_pixel_node_t* bin_find_default_pixel_list(ir_set); void bin_process_frameboxes(ir_set, struct bin_ht_header_t*, struct bin_pixel_node_t*); int bin_process_links(ir_set, ir_setdata); +int bin_process_dlinks(struct bin_processed_lists_t*); /* Init the variant hash table for the set, process the sets links and add them to link_stack and variant hash table, and then output the actual framedata */ @@ -389,16 +393,22 @@ bin_process_sdat struct bin_attachment_list_t attachment_list; struct bin_pixel_node_t *default_pixel_list; struct bin_ht_header_t ht_header; + struct bin_processed_links_t* processed_links_root; long varht_start, varht_size, sdat_start; int num_entries, num_links; - ir_setdata olink_head; sdat_start = ftell(binaryout); /* Alloc position for sdat_header */ fseek(binaryout, sizeof(struct bin_setdata_header_t), SEEK_CUR); - num_links = bin_process_links(set, olink_head); + /* set up root for processed_links */ + processed_links_root = stack_alloc(&plinkpages, bin_processed_links_t); + processed_links_root_val->mlink_len = processed_links_root->vlink_len = 0; + processed_links_root = bin_process_links(set, processed_links_root); + + num_links = processed_links_root->mlink_len + processed_links_root->vlink_len; + num_entries = bin_set_varcount(set) + num_links; HT_INIT(varht_start, varht_size, num_entries); @@ -411,78 +421,111 @@ bin_process_sdat fwrite(&header, sizeof(header), 1, binaryout); fseek(binaryout, 0, SEEK_END); - /* insert the links that were processed into the variant hash table */ - bin_insert_links(num_links, &ht_header, attachment_list.filepos); + /* Process dlinks */ + bin_process_dlinks(processed_links_root); + + /* Determine the default pixel list for all of the frameboxes */ default_pixel_list = bin_find_default_pixel_list(set); /* Output each framebox, and insert it into the variant hash table */ bin_process_frameboxes(set, &ht_header, default_pixel_list); + /* insert the links that were processed into the variant hash table */ + bin_insert_links(processed_links_root, &ht_header, attachment_list.filepos); + /* TODO: Convert the default pixel list to an attachment_list and then push the */ /* sdats attachment_list onto the attachment_stack so it can be procesed */ + /* free plinkpages and datapages */ + return sdat_start; } +static inline +void bin_process_dlinks +( struct bin_processed_links_t* processed_links ) +{ struct bin_linklist_t* olink_iter; + ir_set trg_set; + for( dlink_iter = processed_links->dlink_list; dlink_iter != NULL; dlink_iter = dlink_iter->next) + { /* Construct its fully qualified name based on ?*/ + /* Output an int for its length, and then output the name */ + + + } +} +static inline +struct bin_linklist_t* bin_linklist_head +( struct bin_linklist_t* root ) +{ struct bin_linklist_t* head; + head = root; + while(head->next) + head = head->next; + return head; +} -/* Adds a vlink onto the stack_alloc to be popped during the processing of the - sets variant hash table. If the vlink has a name, its a vlink to a single - variant. if the vlink doesnt have a name, its the vlink to an entire variant - hash table, and each variant (framebox) needs to be added */ -int +/* We dont know src_pos at this point because this is still in the control flow + of bin_process_links, which determines the number of links, which determines + the hash table. */ +void +#define PUSH_LINK(_LINK) (*(linkdata*) stack_alloc(&linkpages, sizeof(linkdata)) = _LINK) bin_process_vlink -( ir_setdata vlink, - ir_set trg_set -) -{ struct bin_plink_t* plp; +( linkdata vlink, + struct bin_processed_links_t* processed_links) +{ struct bin_processed_links_t* plp; + struct bin_linklist_t* vlink_list_head; + linkdata new_vlink; ir_setdata fiter; + ir_set trg_set; uint8_t* link_name; - int num_links; - - num_links = 0; - /* TODO: Macroize? or not worth? */ - link_name = ir_setdata_name(vlink); - - if (link_name) - { plp = struct_alloc(bin_plink_t); - plp->src_pos = 0; // TBD @ process_setdata - plp->name = link_name; - plp->trg_set = trg_set; - plp->type = VLINK; - num_links++; + vlink_list_head = bin_linklist_head(processed_links->vlink_list); + link_name = ir_setdata_name(vlink); + if (link_name) + { plp = struct_alloc(bin_processed_links_t); + plp->linkdata = vlink; + vlink_list_head->next = plp; + processed_links->vlink_len++; + PUSH_LINK(vlink); } else // linking a variant hash table - for (fiter = ir_set_framebox(trg_set); fiter != NULL; fiter = ir_setdata_nextsib(fiter)) - { plp = struct_alloc(bin_plink_t); - plp->src_pos = 0; // TBD @ process_setdata - plp->name = ir_setdata_name(fiter); - plp->trg_set = trg_set; - plp->type = VLINK; - num_links++; + { trg_set = ir_linkdata_set(vlink); + for (fiter = ir_set_framebox(trg_set); fiter != NULL; fiter = ir_setdata_nextsib(fiter)) + { plp = struct_alloc(bin_processed_links_t); + new_vlink = struct_alloc(linkdata); + ir_linkdata_assign_name(new_vlink,ir_setdata_name(fiter)); + ir_linkdata_assign_set(new_vlink,trg_set); + ir_linkdata_assign_type(new_vlink,VLINK); + plp->linkdata = vlink; + vlink_list_head->next = plp; + processed_links->vlink_len++; + PUSH_LINK(vlink); } + } - return num_links; + return processed_links; } /* Adds an mlink to the stack_alloc, to be processed later */ -int +void bin_process_mlink -( ir_setdata mlink, - ir_set trg_set +( linkdata mlink, + bin_processed_links_t* processed_links ) -{ struct bin_plink_t* plp; - uint8_t* mlink_name; - mlink_name = ir_setdata_name(mlink); - plp = struct_alloc(bin_plink_t); - plp->src_pos = 0; //TBD after resolving the childlist | TODO: attach_pos? - if(mlink_name) plp->name = mlink_name; - plp->trg_set = trg_set; - plp->type = MLINK; +{ uint8_t* mlink_name; + struct bin_processed_links_t* mlink_list_head; - return 1; + mlink_list_head = bin_listlist_head(processed_links->mlink_list); + mlink_name = ir_setdata_name(mlink); + plp = stack_alloc(&linkpages, bin_linklist_t); + plp->header.filepos = 0; //TBD after resolving the childlist | TODO: attach_pos? + if(mlink_name) plp->name = mlink_name;// TODO: What does a mlink with a name mean? specifying the framebox mapsheet to use? + plp->trg_set = ir_linkdata_set(mlink); + mlink_list_head->next = plp; + processed_links->mlink_len++; + + return processed_links; } /* TODO: implement this */ @@ -490,91 +533,121 @@ bin_process_mlink if it is, theres a cycle, return 1. Else return 0. */ static inline int olink_cycle -( ir_setdata olink, - ir_setdata olink_head ) -{ ir_setdata iter; - +( linkdata olink, + struct bin_processed_links_t* processed_links +) +{ struct bin_linklist_t* iter; + ir_set olink_set; + olink_set = ir_linkdata_set(olink); + for( iter = processed_links->olink_list; iter != NULL; iter = iter->next) + if(iter == olink_set) + return 1; - return 0; - - } +/* if olink, process target sets frameboxes(turn into vlinks) and its attachment_list (turn into mlink), + else its a dlink so just add it to the processed_links list*/ +static inline +void bin_process_olink +( linkdata olink, + struct bin_processed_links_t* processed_links_root, + ir_set trg_set +) +{ struct bin_linklist_t* link_list_head; + if(trg_set)) //add olink to list so we can check for cycles + { bin_set_frameboxes_vlinks(trg_set, processed_links_root); //TODO: implement + bin_set_attachmentlist_mlink(trg_set, processed_links_root); //TODO: implement + link_list_head = bin_linklist_head(processed_links_root->olink_list); + link_list_head->next = struct_alloc(bin_linklist_t); + link_list_head->next->linkdata = olink; + } + else // olink is actually a dynamic link + { link_list_head = bin_linklist_head(processed_links_root->dlink_list); + link_list_head->next = struct_alloc(bin_linklist_t); + link_list_head->next->linkdata = olink; + } + +} + +struct bin_linklist_t; +struct bin_linklist_t +{ struct bin_linklist_t* next; + linkdata linkdata; +}; + +struct bin_processed_links_t +{ struct bin_linklist_t* vlink_list; + int vlink_len; + struct bin_linklist_t* mlink_list; + int mlink_len; + struct bin_linklist_t* olink_list; //keep track of olink cycles + int olink_len; + struct bin_linklist_t* dlink_list; + int dlink_len; +}; /* Given a set, determine the number of links it has and process each link and then add them to stack_alloc, where they will be popped off and further processed. */ -int -bin_process_links +struct bin_processed_links_t* bin_process_links ( ir_set src_set, - ir_setdata olink_head + struct bin_processed_links_t* processed_links_root; ) -{ int num_links; - linkdata liter; //link iter +{ struct bin_processed_links_t* returned_val; + linkdata linkdata; ir_set trg_set; - - num_links = 0; - - for(liter = ir_set_link(src_set); liter != NULL; liter = ir_setdata_nextsib((ir_setdata) liter)) - { trg_set = ir_set_from_ref(ir_linkdata_ref(liter)); - switch (ir_linkdata_type(liter)) { + for(linkdata = ir_set_link(src_set); linkdata != NULL; linkdata = (linkdata) ir_setdata_nextsib((ir_setdata) linkdata)) + { switch (ir_linkdata_type(linkdata)) { case OLINK: - if (olink_cycle(liter, olink_head)) //TODO: stack of olinks to iterate and check for cycles? - return num_links; - num_links += bin_process_vlink(liter, trg_set); - num_links += bin_process_mlink(liter, trg_set); - num_links += bin_process_links(trg_set, liter); + if (olink_cycle(linkdata, processed_links_root)) + return processed_links_root; //TODO: what return value? + trg_set = ir_linkdata_set(linkdata); + bin_process_olink(trg_set, linkdata, processed_links_root); + bin_process_links(trg_set, processed_links_root); break; case VLINK: - num_links += bin_process_vlink(liter, trg_set); + bin_process_vlink(linkdata, processed_links_root); break; case MLINK: - num_links += bin_process_mlink(liter, trg_set); + bin_process_mlink(linkdata, processed_links_root); break; case ALINK: //TODO: ? break; } } - return num_links; + return processed_links_root; } /* Insert both mlinks and vlinks into the link stack, after determining their src_pos. Vlinks have an additional requirement of being added into the variant hash table */ -#define pop_linkp() (*(struct bin_plink_t**) pagelist_pop(&datapages, sizeof(struct bin_plink_t*))) -#define PUSH_PLINK(_LINK) (*(struct bin_plink_t**) stack_alloc(&linkpages, sizeof (_LINK)) = _LINK ) +#define PUSH_PLINK(_LINK) (*(struct **) stack_alloc(&linkpages, sizeof (_LINK)) = _LINK ) void bin_insert_links -( int num_links, +( struct bin_processed_links_t* links, struct bin_ht_header_t* ht, long attach_pos ) { struct bin_plink_t* plp; struct bin_ht_entry_t ht_entry; - int i; + struct link_list_t* vlinkiter, mlinkiter; + long entry_pos; + /* Insert vlinks into hash table, put v/mlinks on link stack to be processed later */ - for ( i = 0; i < num_links; i++) - { plp = pop_linkp(); - switch (plp->type) { - case MLINK: - plp->trg_set = plp->trg_set; - plp->src_pos = attach_pos; - PUSH_PLINK(plp); - break; - case VLINK: - ht_entry.key = NAMEHASH(plp->name, ht->entries << 1); - ht_entry.value = 0; - bin_insert_ht_entry(ht->start, ht->entries * sizeof(ht_entry), &ht_entry, 0); - plp->src_pos = ht_entry.key + sizeof(ht_entry.key); - PUSH_PLINK(plp); - break; - case OLINK: - break; - //shouldnt exist - case ALINK: - break; - //TBD - } + for ( vlinkiter = links->vlink_root; vlinkiter != NULL; vlinkiter = vlinkiter->next;) + { ht_entry.key = NAMEHASH(ir_setdata_name(vlinkiter->linkdata), ht->entries << 1); + ht_entry.value = 0; + entry_pos = bin_insert_ht_entry(ht->start, ht->entries * sizeof(ht_entry), &ht_entry, 0); + ir_setdata_assign_fpos(vlinkiter->linkdata, entry_pos); + PUSH_PLINK(vlinkiter->linkdata); } + for ( mlinkiter = links->mlink_root; mlinkiter != NULL; mlinkiter = mlinkiter->next) + { >trg_set = plp->trg_set; + plp->src_pos = attach_pos; + PUSH_PLINK(plp); + } + /* Process dlinks here */ + + } long bin_process_facing(ir_setdata, apc_facing, struct bin_pixel_node_t*); @@ -665,7 +738,7 @@ bin_process_facing int num_mapchannels, num_framechannels, x; struct bin_frame_header_t header; long facing_start; - unsigned char* mapdata, * framedata; + RGBA_t* mapdata, * framedata; uint8_t* png_suffix = ".png"; struct bin_pixel_node_t* map_pixel_list; @@ -673,8 +746,8 @@ bin_process_facing /* Set up data pointers to mapsheet and framesheet, as well as their image infos */ - mapdata = stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata) ir_framebox_mapsheet(framebox,SFACE))), &mapsheet_info.width, &mapsheet_info.width, &num_framechannels , 0); - framedata = stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata) ir_framebox_framesheet(framebox,SFACE))), &framesheet_info.width, &framesheet_info.height, &num_mapchannels, 0); + mapdata = (RGBA_t*) stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata) ir_framebox_mapsheet(framebox,SFACE))), &mapsheet_info.width, &mapsheet_info.width, &num_framechannels , 0); + framedata = (RGBA_t*) stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata) ir_framebox_framesheet(framebox,SFACE))), &framesheet_info.width, &framesheet_info.height, &num_mapchannels, 0); bin_set_img_info(&framesheet_info, ir_framebox_framesheet(framebox, SFACE)); bin_set_img_info(&mapsheet_info, ir_framebox_mapsheet(framebox, SFACE)); @@ -829,31 +902,6 @@ bin_insert_node_into_list } -/* TODO: Finish this */ -struct bin_pixel_node_t* -bin_process_pixel -( unsigned char* data, - int x, - int y, - int init_height, - int init_width -) -{ struct bin_pixel_node_t* pixel_node = NULL; - if(*data) - { pixel_node = struct_alloc(bin_pixel_node_t); - /* get ref from 4 bytes of data */ - pixel_node->data.ref = (int) data; - /* bitshift by ? to get Z */ - pixel_node->data.z = ((int) data << 24); - /* set x and y */ - pixel_node->data.x = x + init_width ; - pixel_node->data.y = y + init_width; - } - *data += 4; - return pixel_node; - -} - /* Returns the non null pixels of a single map */ /* TODO: Finish this */ struct bin_pixel_node_t* @@ -861,10 +909,10 @@ bin_mapframe_to_pixel_list ( struct bin_img_info_t* img_info, int init_height, int init_width, - unsigned char* data + RBGA_t* data ) { int x, y, fheight, fwidth; - struct bin_pixel_node_t* pixel_list, * pixel_node; + struct bin_pixel_node_t* pixel_list,* pixel_node; pixel_list = NULL; @@ -890,13 +938,22 @@ bin_mapframe_to_pixel_list /* Process the map*/ for (y = 0; y < fheight; y++) { for ( x = 0; x < fwidth; x++ ) - { pixel_node = bin_process_pixel(data, x, y, init_height, init_width); - pixel_list = bin_insert_node_into_list(pixel_list, pixel_node); - data += img_info->width - img_info->fwidth; //stride - } + { if (*data) + { pixel_node = struct_alloc(bin_pixel_node_t); + /* get ref from 4 bytes of data */ + pixel_node->data.ref = (*data) >> 8; + /* bitshift by ? to get Z */ + pixel_node->data.z = (*data & 0xFF); + /* set x and y */ + pixel_node->data.x = x + init_width; + pixel_node->data.y = y + init_width; + pixel_list = bin_insert_node_into_list(pixel_list, pixel_node); + } + data++; + } + data += img_info->width - img_info->fwidth; //stride } - - return pixel_list; + return pixel_list; } static inline @@ -948,14 +1005,14 @@ bin_find_default_pixel_list ( ir_set set) { ir_setdata fiter; struct bin_pixel_node_t* default_pixel_list, * curr_pixel_list; - unsigned char* data; + RGBA_t* data; int num_channels; struct bin_img_info_t img_info; for (fiter = ir_set_framebox(set); fiter != NULL; fiter = ir_setdata_nextsib(fiter)) { /* TODO: Stringify the frame name with .png? */ /* TODO: Add directory changing */ - data = stbi_load(ir_setdata_name((ir_setdata) ir_framebox_mapsheet(fiter,SFACE) ), &img_info.width, &img_info.width, &num_channels, 0); + data = (RGBA_t*) stbi_load(ir_setdata_name((ir_setdata) ir_framebox_mapsheet(fiter,SFACE) ), &img_info.width, &img_info.width, &num_channels, 0); bin_set_img_info(&img_info, ir_framebox_mapsheet(fiter, SFACE)); curr_pixel_list = bin_mapframe_to_pixel_list(&img_info, 0, 0, data); default_pixel_list = bin_cmp_default_pixel_lists(curr_pixel_list, default_pixel_list);