/* 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 */
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;
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;
}
return 0;
}
+
+typedef RGBA_t uint32_t;
+
long bin_traverse_class(ir_class);
/* Takes root class and begins processing */
void
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,
INC_ENTRY();
}
WRITE_ENTRY();
+
+ return entry_pos;
}
}
/* | sdat header |
+ |------------------|
+ | num dlinks |
+ |------------------|
+ | dlink len |
+ |------------------|
+ | dlink string |
|------------------|
| variant ht |
|------------------|
*/
-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 */
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);
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 */
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*);
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;
/* 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));
}
-/* 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*
( 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;
/* 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
( 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);