Index: class.c ================================================================== --- class.c +++ class.c @@ -129,10 +129,11 @@ #define MAC_BIT 0xFFCA #define MAC_VERSION 0xFFE0 #define MAC_DEFINE 0xFFE1 #define MAC_INCLUDE 0xFFE2 #define MAC_CALL 0xFFE3 +#define MAC_APPEND 0xFFE4 #define MAC_UNDEFINED 0xFFFF static TokenList*add_macro(void) { TokenList*o=malloc(sizeof(TokenList)); if(!o) fatal("Allocation failed\n"); @@ -543,31 +544,47 @@ ParseError("Invalid Hero Mesh key name: %s\n",tokenstr); break; } } -static void define_macro(Uint16 name) { +static void define_macro(Uint16 name,Uint8 q) { int i; TokenList**t; + if(main_options['M']) printf("M< %04X %04X \"%s\" %d\n",name,glohash[name].id,glohash[name].txt,q); if(glohash[name].id<0xC000) fatal("Confusion\n"); if(glohash[name].idnext; i=1; for(;;) { nxttok1(); + if(main_options['L'] && main_options['M']) { + int j; + printf("*: %5d %04X %08X \"",i,tokent,tokenv); + for(j=0;tokenstr[j];j++) { + if(tokenstr[j]<32 || tokenstr[j]>126) printf("<%02X>",tokenstr[j]&255); + else putchar(tokenstr[j]); + } + printf("\"\n"); + } if(tokent==TF_MACRO+TF_OPEN && ++i>65000) ParseError("Too much macro nesting\n"); if(tokent==TF_MACRO+TF_CLOSE && !--i) break; *t=add_macro(); t=&(*t)->next; } + if(main_options['M']) printf("M> %04X %04X %p\n",name,glohash[name].id,macros[glohash[name].id-0xC000]); } static void begin_include_file(const char*name) { InputStack*nxt=inpstack; inpstack=malloc(sizeof(InputStack)); @@ -816,11 +833,11 @@ macros=calloc(MAX_MACRO,sizeof(TokenList*)); if(!macros) fatal("Allocation failed\n"); } nxttok(); if(!(tokent&TF_NAME) || tokenv!=OP_STRING) ParseError("String literal expected\n"); - define_macro(look_hash_mac()); + define_macro(look_hash_mac(),1); goto again; case MAC_INCLUDE: if(macstack) ParseError("Cannot use {include} inside of a macro\n"); nxttok1(); if(tokent==TF_MACRO && tokenv==1) ReturnToken(TF_EOF,0); @@ -833,10 +850,19 @@ case MAC_CALL: nxttok(); if(!(tokent&TF_NAME) || tokenv!=OP_STRING) ParseError("String literal expected\n"); tokenv=look_hash_mac(); goto call; + case MAC_APPEND: + if(!macros) { + macros=calloc(MAX_MACRO,sizeof(TokenList*)); + if(!macros) fatal("Allocation failed\n"); + } + nxttok(); + if(!(tokent&TF_NAME) || tokenv!=OP_STRING) ParseError("String literal expected\n"); + define_macro(look_hash_mac(),0); + goto again; case MAC_UNDEFINED: ParseError("Undefined macro: {%s}\n",tokenstr); break; default: ParseError("Strange macro token: 0x%04X\n",glohash[tokenv].id); @@ -1611,10 +1637,11 @@ strcpy(tokenstr,"bit"); glohash[look_hash_mac()].id=MAC_BIT; strcpy(tokenstr,"version"); glohash[look_hash_mac()].id=MAC_VERSION; strcpy(tokenstr,"define"); glohash[look_hash_mac()].id=MAC_DEFINE; strcpy(tokenstr,"include"); glohash[look_hash_mac()].id=MAC_INCLUDE; strcpy(tokenstr,"call"); glohash[look_hash_mac()].id=MAC_CALL; + strcpy(tokenstr,"append"); glohash[look_hash_mac()].id=MAC_APPEND; if(main_options['L']) { for(;;) { nxttok(); printf("** %5d %04X %08X \"",linenum,tokent,tokenv); for(i=0;tokenstr[i];i++) { Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -129,10 +129,14 @@ {* } Multiplication. The result is 1 if no arguments are specified. {/ } Division. + +{append } + This works like {define} but adds to an existing definition rather than + replacing the definition. {band } Bitwise AND. The result is -1 if no arguments are specified. {bit } Index: mbtofhm.c ================================================================== --- mbtofhm.c +++ mbtofhm.c @@ -412,11 +412,11 @@ } #define SubOpcode(...) do{ static const char*const ss[]={__VA_ARGS__}; if(*op>=sizeof(ss)/sizeof(*ss)) goto unknown; fprintf(fp," %s",ss[*op]); }while(0) #define PushFlowControl() do{ flowblock[flowptr]=ofs+2+(op[1]<<1)+(op[2]<<9); if(++flowptr==64) fatal("Too many nested flow controls\n"); len+=2; ind+=2; }while(0) -static void class_codes(FILE*fp,const unsigned char*op,int ofs,const unsigned char*lbl,int nlbl,const unsigned char*subs,int nsubs,unsigned char*vars) { +static void class_codes(FILE*fp,const unsigned char*op,int ofs,const unsigned char*lbl,int nlbl,const unsigned char*subs,int nsubs,unsigned char*vars,const char*cname) { static const char*const stdvars[256]={ [0]="Class","Temperature","Shape", [4]="Xloc","Yloc","Dir","Image","Inertia","Misc1","Misc2","Misc3","Misc4","Misc5","Misc6","Misc7", [16]="Arrived","Departed","Arrivals","Departures", [32]="Busy","Invisible","UserSignal","UserState","KeyCleared","Player","Destroyed","Stealthy","VisualOnly", @@ -560,10 +560,19 @@ fprintf(fp," Self"); break; case 40: fprintf(fp," ObjClassAt"); break; + case 47: + z=-1; + for(x=0;x>1) break; + y--; + x+=10; + } + if(z!=-1) fprintf(fp,"{Array @%s.%s %d %d}",cname,lbl+z*10,op[1],op[3]); + len+=4*(op[1]*op[3]+1); + } st=0; break; case 126: fprintf(fp," Animate"); st=0; break; case 127: case 128: @@ -883,21 +912,21 @@ fprintf(fp," (Sharp %d)\n",c->attr[38]|(c->attr[39]<<8)); } } if(c->subscode[1] || c->subscode[0]>2) { fprintf(fp," (SUBS"); - class_codes(fp,c->subscode+2,2,c->subslbl,c->nsubslbl,c->subslbl,c->nsubslbl,c->vars); + class_codes(fp,c->subscode+2,2,c->subslbl,c->nsubslbl,c->subslbl,c->nsubslbl,c->vars,c->name); fprintf(fp,"\n )\n"); } o=4; for(i=0;inmsgs;i++) { fprintf(fp," ("); j=c->msgscode[i][0]|(c->msgscode[i][1]<<8); if(j<20) fprintf(fp,"%s",standard_message_names[j]); else if(j-20msgscode[i]+4,o,c->msgslbl,c->nmsgslbl,c->subslbl,c->nsubslbl,c->vars); + class_codes(fp,c->msgscode[i]+4,o,c->msgslbl,c->nmsgslbl,c->subslbl,c->nsubslbl,c->vars,c->name); o+=(c->msgscode[i][2]<<1)|(c->msgscode[i][3]<<9); fprintf(fp,"\n )\n"); } fprintf(fp,")\n"); }