From b14fd3a9556894089856bbee50ebe727d9b64635 Mon Sep 17 00:00:00 2001 From: ken Date: Wed, 22 Feb 2017 10:52:08 -0800 Subject: [PATCH] face mirroring --- src/ir.c | 142 +++++++++++++++++++++++++++++++++++++++------------ src/ir.h | 61 ++++++++++++---------- src/parser.y | 32 +++++++----- 3 files changed, 161 insertions(+), 74 deletions(-) diff --git a/src/ir.c b/src/ir.c index bdf0d36..857f73f 100644 --- a/src/ir.c +++ b/src/ir.c @@ -32,6 +32,11 @@ int ir_linker(void); int ir_condenser(void); /* Set data mem */ enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; +struct ir_facinglist_t; +struct ir_facinglist_t +{ struct ir_facinglist_t* nextsib; + apc_facing facing; +}; struct ir_namelist_t; struct ir_namelist_t { struct ir_namelist_t* nextsib; @@ -54,7 +59,9 @@ struct ir_setdata_header_t }; struct ir_framedata_t { struct ir_setdata_header_t header; - struct ir_frameinfo_t frameinfo; + apc_facing facing; + int w, h; + struct ir_facinglist_t* mirrorlist,* nextmirror; }; struct ir_framebox_t { struct ir_setdata_header_t header; @@ -96,7 +103,7 @@ struct ir_set_t 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); +union ir_setdata_t* ir_framedata (enum dtype,const uint8_t*,facinglist,int,int); static inline void ir_linkdata_resolve_set(union ir_setdata_t*); static inline @@ -398,17 +405,17 @@ void ir_set_assign_data 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) + if (framebox->framesheets[setdata->framesheet.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; + setdata->framesheet.facing, setdata->header.data_name); + framebox->framesheets[setdata->framesheet.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) + if (framebox->mapsheets[setdata->mapsheet.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; + setdata->mapsheet.facing, setdata->header.data_name); + framebox->mapsheets[setdata->mapsheet.facing] = setdata->mapsheet; break; case ADAT: if (set->audio == NULL) @@ -486,28 +493,28 @@ void ir_data_assign_path } union ir_setdata_t* ir_framesheet -( const uint8_t* name, - apc_facing d, - int width, - int height +( const uint8_t* name, + struct ir_facinglist_t* facinglist, + int width, + int height ) -{ return ir_framedata(FSDAT, name, d, width, height); } +{ return ir_framedata(FSDAT, name, facinglist, width, height); } union ir_setdata_t* ir_mapsheet -( const uint8_t* name, - apc_facing d, - int width, - int height +( const uint8_t* name, + struct ir_facinglist_t* facinglist, + int width, + int height ) -{ return ir_framedata(MSDAT, name, d, width, height); } +{ return ir_framedata(MSDAT, name, facinglist, width, height); } static inline union ir_setdata_t* ir_framedata -( enum dtype type, - const uint8_t* name, - apc_facing d, - int width, - int height +( enum dtype type, + const uint8_t* name, + struct ir_facinglist_t* facinglist, + int width, + int height ) { struct ir_framedata_t* framedata = struct_alloc(ir_framedata_t); struct_clear(framedata); @@ -515,9 +522,17 @@ union ir_setdata_t* ir_framedata 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; + if (facinglist != NULL) + { framedata->facing = facinglist->facing; + framedata->mirrorlist = facinglist->nextsib; + } + else + { framedata->facing = SFACE; + framedata->mirrorlist = NULL; + } + framedata->nextmirror = framedata->mirrorlist; + framedata->w = width; + framedata->h = height; return (union ir_setdata_t*) framedata; } @@ -834,13 +849,40 @@ void ir_setdata_assign_name ( union ir_setdata_t* setdata, uint8_t* name ) { setdata->header.data_name = name;} +/* Create a new facinglist from an apc_facing */ +struct ir_facinglist_t* ir_facinglist +( apc_facing facing ) +{ struct ir_facinglist_t* list = struct_alloc(ir_facinglist_t); + list->facing = facing; + return list; +} + +/* Add a child to the facing list */ +struct ir_facinglist_t* ir_facinglist_push +( struct ir_facinglist_t* list, + apc_facing facing +) +{ struct ir_facinglist_t* iter = list; + if (iter != NULL) + { while (iter->nextsib != NULL) + iter = iter->nextsib; + iter->nextsib = struct_alloc(ir_facinglist_t); + iter->nextsib->facing = facing; + } + return list; +} + +#define assert_framebox(fbox) if (DEBUG) { \ + if (fbox->header.type != FBDAT) \ + eprintf("Data %s is not a framebox\n", fbox->header.data_name); \ + } + /* Return a framebox's specified framesheet */ union ir_setdata_t* ir_framebox_framesheet ( union ir_setdata_t* fbox, apc_facing facing ) -{ if (fbox->header.type != FBDAT) - eprintf("Data %s is not a framebox\n", fbox->header.data_name); +{ assert_framebox(fbox); return (union ir_setdata_t*) &fbox->framebox.framesheets[facing]; } @@ -849,19 +891,51 @@ union ir_setdata_t* ir_framebox_mapsheet ( union ir_setdata_t* fbox, apc_facing facing ) -{ if (fbox->header.type != FBDAT) - eprintf("Data %s is not a framebox\n", fbox->header.data_name); +{ assert_framebox(fbox); return (union ir_setdata_t*) &fbox->framebox.mapsheets[facing]; } +#define assert_framedata(fdat) if (DEBUG) { \ + if (fdat->header.type != MSDAT && fdat->header.type != FSDAT) \ + eprintf("Data %s is not a framedata\n", fdat->header.data_name); \ + } + +/* Return a framedata's frame info */ +int ir_framedata_width +( union ir_setdata_t* framedata ) +{ assert_framedata(framedata); + return framedata->mapsheet.w; +} + /* Return a framedata's frame info */ -struct ir_frameinfo_t* ir_framedata_frameinfo +int ir_framedata_height ( union ir_setdata_t* framedata ) -{ if (framedata->header.type != MSDAT && framedata->header.type != FSDAT) - eprintf("Data %s is not a framedata\n", framedata->header.data_name); - return &framedata->mapsheet.frameinfo; +{ assert_framedata(framedata); + return framedata->mapsheet.h; } +/* Return the next facing in the framedata's facing list, and reset the + 'nextmirror' head to mirrorlist, so that 'ir_framedata_nextmirror' will now + refer to the second facing in the framedata */ +apc_facing ir_framedata_firstfacing +( union ir_setdata_t* framedata ) +{ assert_framedata(framedata); + framedata->mapsheet.nextmirror = framedata->mapsheet.mirrorlist; + return framedata->mapsheet.facing; +} + +/* Return the next facing for this framedata, incrementing the 'nextmirror' + head. Returns FACING_MAX when there are no more facings to return. */ +apc_facing ir_framedata_nextfacing +( union ir_setdata_t* framedata ) +{ apc_facing facing; + assert_framedata(framedata); + if (framedata->mapsheet.nextmirror == NULL) + return FACING_MAX; + facing = framedata->mapsheet.nextmirror->facing; + framedata->mapsheet.nextmirror = framedata->mapsheet.nextmirror->nextsib; + return facing; +} /** Allocators **/ static diff --git a/src/ir.h b/src/ir.h index 3dd4264..b19b2d3 100644 --- a/src/ir.h +++ b/src/ir.h @@ -22,14 +22,13 @@ #include #include "apc.h" -struct ir_frameinfo_t -{ int facing, w, h; }; -typedef union ir_setdata_t* ir_setdata; -typedef struct ir_frameinfo_t* ir_frameinfo; -typedef struct ir_set_t* ir_set; -typedef struct ir_class_t* ir_class; -typedef struct ir_setld_t* ir_setld; -typedef struct ir_classld_t* ir_classld; +typedef union ir_setdata_t* ir_setdata; +typedef struct ir_frameinfo_t* ir_frameinfo; +typedef struct ir_set_t* ir_set; +typedef struct ir_class_t* ir_class; +typedef struct ir_setld_t* ir_setld; +typedef struct ir_classld_t* ir_classld; +typedef struct ir_facinglist_t* facinglist; /* Classes and Sets Classes are rooted at a special root class, representing the current working directory at scan-time, named ".". The root class can always be identified @@ -86,28 +85,36 @@ enum ltype { OLINK, MLINK, VLINK, ALINK }; void ir_set_assign_data(ir_set,ir_setdata); void ir_set_assign_ref(ir_set,uint32_t); void ir_data_assign_path(ir_setdata,const uint8_t*); -ir_setdata ir_framesheet(const uint8_t*, apc_facing, int,int); -ir_setdata ir_mapsheet(const uint8_t*, apc_facing, int,int); +ir_setdata ir_framesheet(const uint8_t*,facinglist,int,int); +ir_setdata ir_mapsheet(const uint8_t*,facinglist,int,int); ir_setdata ir_audio(const uint8_t*); ir_setdata ir_link(enum ltype,ir_setld,const uint8_t*); +/* Facing Lists for creating frame/mapsheets */ +facinglist ir_facinglist(apc_facing); +facinglist ir_facinglist_push(facinglist,apc_facing); /* Output */ -framebox ir_set_framebox(ir_set); -audiodata ir_set_audio(ir_set); -linkdata ir_set_link(ir_set); -enum ltype ir_linkdata_type(linkdata); -uint32_t ir_linkdata_ref(linkdata); -ir_set ir_linkdata_set(linkdata); -void ir_linkdata_assign_set(linkdata,ir_set); -void ir_linkdata_assign_type(linkdata,enum ltype); -uint8_t* ir_linkdata_dlink_name(linkdata); -ir_setdata ir_setdata_nextsib(ir_setdata); -uint8_t* ir_setdata_name(ir_setdata); -uint8_t* ir_setdata_filename(ir_setdata); -long ir_setdata_fpos(ir_setdata); -void ir_setdata_assign_fpos(ir_setdata,long); -framedata ir_framebox_framesheet(framebox,apc_facing); -framedata ir_framebox_mapsheet(framebox,apc_facing); -ir_frameinfo ir_framedata_frameinfo(framedata); +framebox ir_set_framebox(ir_set); +audiodata ir_set_audio(ir_set); +linkdata ir_set_link(ir_set); +enum ltype ir_linkdata_type(linkdata); +uint32_t ir_linkdata_ref(linkdata); +ir_set ir_linkdata_set(linkdata); +void ir_linkdata_assign_set(linkdata,ir_set); +void ir_linkdata_assign_type(linkdata,enum ltype); +uint8_t* ir_linkdata_dlink_name(linkdata); +ir_setdata ir_setdata_nextsib(ir_setdata); +uint8_t* ir_setdata_name(ir_setdata); +uint8_t* ir_setdata_filename(ir_setdata); +long ir_setdata_fpos(ir_setdata); +void ir_setdata_assign_fpos(ir_setdata,long); +void ir_setdata_assign_name(ir_setdata,uint8_t*); +/* Framedata */ +framedata ir_framebox_framesheet(framebox,apc_facing); +framedata ir_framebox_mapsheet(framebox,apc_facing); +int ir_framedata_width(framedata); +int ir_framedata_height(framedata); +apc_facing ir_framedata_firstfacing(framedata); +apc_facing ir_framedata_nextfacing(framedata); /* Reference Linking Data Create linking data to sets or classes that will be resolved at a later stage. Class references can be created from an ir_class object, if diff --git a/src/parser.y b/src/parser.y index 5dc5fdb..2c74db7 100644 --- a/src/parser.y +++ b/src/parser.y @@ -5,7 +5,7 @@ #include "ir.h" #include "apc.h" typedef struct class_state_t yycstate; - struct frame_spec_t { apc_facing d; int w, h; }; + struct frame_spec_t { facinglist list; int w, h; }; } %code provides { yycstate* yycstate_new(void); @@ -49,6 +49,7 @@ ir_setld ld; ir_setdata data; struct frame_spec_t frame_spec; + facinglist facinglist; } /* Operators */ %token CLOPEN //( @@ -64,10 +65,11 @@ %token FACING %token NAME /* Types */ -%type data_spec -%type set_spec -%type set_ld set_link -%type frame_spec +%type data_spec +%type set_spec +%type set_ld set_link +%type frame_spec +%type facing_list %% /* Syntax Directed Translation Scheme of the APC grammar */ progn: @@ -100,10 +102,10 @@ statement_list: ; data_spec: - SS NAME frame_spec { $$ = ir_framesheet($2,$3.d,$3.w,$3.h); } -| SS frame_spec { $$ = ir_framesheet(DEFAULT_VARIANT,$2.d,$2.w,$2.h); } -| MAP NAME frame_spec { $$ = ir_mapsheet($2,$3.d,$3.w,$3.h); } -| MAP frame_spec { $$ = ir_mapsheet(DEFAULT_VARIANT,$2.d,$2.w,$2.h); } + SS NAME frame_spec { $$ = ir_framesheet($2,$3.list,$3.w,$3.h); } +| SS frame_spec { $$ = ir_framesheet(DEFAULT_VARIANT,$2.list,$2.w,$2.h); } +| MAP NAME frame_spec { $$ = ir_mapsheet($2,$3.list,$3.w,$3.h); } +| MAP frame_spec { $$ = ir_mapsheet(DEFAULT_VARIANT,$2.list,$2.w,$2.h); } | AUDIO NAME { $$ = ir_audio($2); } | LINK set_ld { $$ = ir_link(OLINK, $2, NULL); } | LINK set_ld MAP { $$ = ir_link(MLINK, $2,NULL); } @@ -129,11 +131,15 @@ set_ld: | REF { $$ = ir_setld_from_ref($1); } ; +facing_list: + facing_list FACING { $$ = ir_facinglist_push($1,$2); } +| FACING { $$ = ir_facinglist($1); } + frame_spec: - NUM NUM { $$ = (struct frame_spec_t) {SFACE,$1,$2}; } -| FACING { $$ = (struct frame_spec_t) {$1,0,0}; } -| FACING NUM NUM { $$ = (struct frame_spec_t) {$1,$2,$3}; } -| %empty { $$ = (struct frame_spec_t) {SFACE,0,0}; } + NUM NUM { $$ = (struct frame_spec_t) {NULL,$1,$2}; } +| facing_list { $$ = (struct frame_spec_t) {$1,0,0}; } +| facing_list NUM NUM { $$ = (struct frame_spec_t) {$1,$2,$3}; } +| %empty { $$ = (struct frame_spec_t) {NULL,0,0}; } ; %% -- 2.18.0