From 9aae885b30d1325721b77ad072007af7089d7b69 Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 11 Jan 2017 14:31:19 -0800 Subject: [PATCH] wip --- src/ir.c | 406 +++++++++++++++++++++++++++++++++++++++++-------------- src/ir.h | 10 +- 2 files changed, 312 insertions(+), 104 deletions(-) diff --git a/src/ir.c b/src/ir.c index 49480ab..76c221d 100644 --- a/src/ir.c +++ b/src/ir.c @@ -19,75 +19,71 @@ #include "ir.h" /* Public */ int ir_init(void); +void ir_quit(void); int ir_linker(void); int ir_condenser(void); -#if 0 -ir_class ir_class_findchild(ir_class, uint8_t*); -ir_set ir_class_rootset(ir_class); -ir_class ir_class_nextsib(ir_class); -ir_class ir_class_nextchild(ir_class); -uint8_t* ir_class_name(ir_class); -ir_set ir_class_findset(ir_class,uint8_t*); -ir_set ir_set_findchild(ir_set, uint8_t*); -ir_set ir_set_nextsib(ir_set); -ir_set ir_set_nextchild(ir_set); -ir_set ir_set_findref(long long); -uint8_t* ir_set_name(ir_set); -#endif /* Private */ +extern //apc.c +long sys_pagesize; +static + +static inline +struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*, uint8_t*); +static inline +void ir_quit_r(struct pagenode_t*); static inline -uint8_t bytes_identical(uint8_t*,uint8_t*); +int bytes_identical(uint8_t*,uint8_t*); /* Enumerated types */ -enum dtype { FSDAT, MSDAT, ADAT, LDAT }; +enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; enum ltype { OLINK, MLINK, VLINK, ALINK }; /* Set data mem */ -struct sdat_header_t -{ enum dtype type; - uint8_t* src_file_name; - uint8_t* data_name; +struct ir_setdata_header_t +{ enum dtype type; + uint8_t* src_filename, * data_name; + union ir_setdata_t* nextsib; }; -struct frameinfo_t -{ int facing, w, h; +struct ir_frameinfo_t +{ int facing, w, h; }; +struct ir_framedata_t +{ struct ir_setdata_header_t header; + struct ir_frameinfo_t frameinfo; +}** framedatas; +struct ir_framebox_t +{ struct ir_setdata_header_t header; + struct ir_framedata_t framesheets[FACING_MAX]; + struct ir_framedata_t mapsheets[FACING_MAX]; +}** frameboxes; +struct ir_simplex_t +{ struct ir_setdat_header_t header; +}** simplexes; +struct ir_link_t +{ struct ir_setdat_header_t header; + struct ir_set_t* src, * trg; + enum ltype type; +}** links; +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 framedata_t -{ struct sdat_header_t header; - struct frameinfo_t frameinfo; -} **framedatas; -struct framebox_t -{ struct framedata_t framesheets[FACE_MAX]; - struct framedata_t mapsheets[FACE_MAX]; - uint8_t *data_name; -} **frameboxes; -struct simplex_t -{ struct sdat_header_t header; -} **simplexes; -struct link_t -{ struct sdat_header_t header; - struct set_t *src, *trg; - enum ltype type; -} **links; -union sdat_t -{ struct sdat_header_t header; - struct framedata_t framesheet; - struct framedata_t mapsheet; - struct simplex_t audio; - struct link_t link; -}; -struct ir_class -{ struct class_t *parent, *nextchild, *nextsib; - struct set_t *root_set; - uint8_t *name; -} **classes; -struct ir_set -{ struct set_t *parent, *nextchild, *nextsib; - struct class_t *class; - uint8_t *name; - struct framebox_t **sprites; - struct framebox_t **maps; - struct simplex_t **audio; - struct link_t **links; -} **sets; +struct ir_class_t +{ struct ir_class_t* nextchild, * nextsib; + struct ir_set_t* root_set; + uint8_t* name; +}** classes; +struct ir_set_t +{ struct ir_set_t* nextchild, * nextsib; + struct ir_class_t* class; + long long ref; + uint8_t* name; + struct framebox_t* frameboxes; + struct simplex_t* audio; + struct link_t* links; +}** sets; /* Function-Like Macros */ #define do_warn() do { \ } while (0) @@ -95,7 +91,7 @@ struct ir_set fprintf(stderr, str); \ do_warn(); \ } while (0) -#define wprintf(fmt,...) do { \ + #define wprintf(fmt,...) do { \ fprintf(stderr, fmt, __VA_ARGS__); \ do_warn(); \ } while (0) @@ -110,13 +106,48 @@ struct ir_set fprintf(stderr, fmt, __VA_ARGS__); \ do_error(); \ } while (0) +#define struct_alloc(_T) ((struct _T*) stack_alloc(sizeof(struct _T))) + static -struct ir_class root_class = { .name = &"." }; +struct ir_class_t root_class = { .name = "." }; /* Init */ int ir_init ( void ) +{ pagenode_root = calloc(struct pagenode_t*) calloc(PN_ALLOCSIZE); + if (pagenode_root == NULL) + return -1; + pagenode_root->head = pagenode_root->root; + pagenode_head = pagenode_root; + return 0; +} + +/* Quit/Cleanup + Recursively clean pagenode linked list +*/ +void ir_quit +( void ) +{ ir_quit_r(pagenode_root); } + +static inline +void ir_quit_r +( struct pagenode_t* pagenode ) +{ if (pagenode->next != NULL) + ir_quit_r(pagenode->next); + free(pagenode); +} + +/* Link +*/ +int ir_linker +( void ) +{ return 0; } + +/* Condense +*/ +int ir_condenser +( void ) { return 0; } /* Return a pointer to the root class */ @@ -125,70 +156,99 @@ struct ir_class_t* ir_class_root { return &root_class; } /* Add a subclass to a class - Attempts to create a new subclass in the provided class, exiting with an - error if the class already exists + Attempts to create a new subclass in the provided class, returning + the class if it already exists */ -#define ERR_DUPECLASS "Subclass %s of class %s already exists!", name, *class.name struct ir_class_t* ir_class_addchild ( struct ir_class_t* class, uint8_t* name ) -{ struct ir_class_t* iter = *class.nextchild; - if (iter == NULL) - return *class.nextchild = class_alloc(name); - iterate: - if (bytes_identical(*iter.name, name)) - { fprintf(stderr, ERR_DUPECLASS); - exit(-1); - } - if (*iter.nextsib != NULL) - { iter = *iter.nextsib; - goto iterate; +{ 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; } - return *iter.nextsib = class_alloc(name); - + return iter->nextsib = struct_alloc(ir_class_t); } -/* Return a pointer to the parent of the provided class */ -struct ir_class_t* ir_class_parent -( struct ir_class_t* class ) -{ return class.parent; } - /* Add a set to a class - Attempts to create a new root set in the specified class, exiting with an - error if the set already exists + Attempts to create a new root set in the specified class, returning + the set if it already exists */ -#define ERR_DUPESET "Root set %s of class %s already exists!", name, *class.name struct ir_set_t* ir_class_addset ( struct ir_class_t* class, uint8_t* name ) -{ struct ir_set_t* iter = *class.root_set; - if (iter == NULL) - return *class.root_set = set_alloc(name); - iterate: - if (bytes_identical(*iter.name, name)) - { fprintf(stderr, ERR_DUPSET); - exit(-1); +{ 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; } - if (*iter.nextsib != NULL) - { iter = *iter.nextsib; - goto iterate; - } - return *iter.nextsib = set_alloc(name); + return iter->nextsib = struct_alloc(ir_set_t); } +/* 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; + } + return iter->nextsib = struct_alloc(ir_set_t); +} + +/* 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.name, name)) + return iter; + if (iter->header.nextsib != NULL) + { iter = iter->header.nextsib; + goto check; + } + return iter->header.nextsib = struct_alloc(ir_framebox_t); +} /* Match two null-terminated bytestrings Return 1 if the two bytestrings are identical, else 0 */ static inline -uint8_t bytes_identical +int bytes_identical ( uint8_t* stra, uint8_t* strb ) @@ -197,3 +257,151 @@ uint8_t bytes_identical return 0; return *stra == *strb; } + +/* 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.name); + if (framebox->framesheets[setdata->framesheet.frameinfo.facing] != 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.name); + if (framebox->mapsheets[setdata->mapsheet.frameinfo.facing] != 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 = &setdata->audio; + 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; + return; + } + else + simplex = simplex->header.nextsib; + simplex->header.nextsib = &setdata->audio; + break; + case LDAT: + if (set->links == NULL) + { set->links = &setdata->link; + return; + } + link = set->links; + while (link->header.nextsib != NULL) + link = link->header.nextsib; + link->header.nextsib = &setdata->link; + break; + default: + fprintf(stderr, "Unknown setdata type %x\n", setdata->header.type); + exit(-1); + } +} + +void ir_set_assign_ref +( ir_set_t* set, + long long ref +) +{ if (set->ref != 0) + wprintf("Ref override: 0x%x -> 0x%x for set %s\n", + set->ref, ref, set->name); + set->ref = ref; + //TODO: reflist_add(set); +} + +void ir_data_assign_path +( union ir_setdata_t* setdata, + uint8_t* path +) +{ if (set->header.src_filename) + wprintf("Path override: %s -> %s for set %s\n", + set->header.src_filename, path, set->name); + set->header.src_filename = path; + //TODO: internal strdup, not assign (= path;) +} + + +//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; +} + +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; +} + +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; +} + + +#define PN_ALLOCSIZE (sys_pagesize) +#define PN_HEADERSIZE() (sizeof(struct pagenode_t*) + sizeof(void*)) +#define PN_MEMSIZE() (PN_ALLOCSIZE - PN_HEADERSIZE()) +#define PN_HEADSIZE() (pagenode_head->head - pagenode_head->root) +#define PN_HEADSPACE() (PN_MEMSIZE() - PN_HEADSIZE()) +struct pagenode_t { + struct pagenode_t* next; + char* head; + char root[]; +}* pagenode_root, * pagenode_head; + + +static +void* stack_alloc(size_t bytes) +{ if (!bytes) + { wprint("Attempting to allocate 0 bytes in stack_alloc"); + return pagenode_head->head; + } + if (PN_HEADSPACE() < bytes) + { pagenode_head->next = (struct pagenode_t*) calloc(PN_ALLOCSIZE); + pagenode_head = pagenode_head->next; + pagenode_head->head = pagenode_head->root; + } + pagenode_head->head += bytes; + return (void*) pagenode_head->head - bytes; +} + diff --git a/src/ir.h b/src/ir.h index 1a7d1a7..7c1f4b3 100644 --- a/src/ir.h +++ b/src/ir.h @@ -20,9 +20,9 @@ #ifndef _IR_H_ #define _IR_H_ #include -enum frame_facing { SFACE, SWFACE, WFACE, NWFACE, NFACE, NEFACE, EFACE, SEFACE, FACING_MAX }; -typedef enum frame_facing ir_facing; -typedef union ir_set_data_t* ir_setdata; +#include "apc.h" + +typedef union ir_setdata_t* ir_setdata; typedef struct ir_set_t* ir_set; typedef struct ir_class_t* ir_class; typedef struct ir_setld_t* ir_setld; @@ -65,8 +65,8 @@ ir_set ir_set_addchild(ir_set,uint8_t*); void ir_set_assign_data(ir_set,ir_setdata); void ir_set_assign_ref(ir_set,long long); void ir_data_assign_path(ir_setdata,uint8_t*); -ir_setdata ir_framesheet(uint8_t*,ir_facing,int,int); -ir_setdata ir_mapsheet(uint8_t*,ir_facing,int,int); +ir_setdata ir_framesheet(uint8_t*, apc_facing, int,int); +ir_setdata ir_mapsheet(uint8_t*, apc_facing, int,int); ir_setdata ir_audio(uint8_t*); ir_setdata ir_link_odat(ir_setld); ir_setdata ir_link_vdat(ir_setld,uint8_t*); -- 2.18.0