Index: bindings.doc ================================================================== --- bindings.doc +++ bindings.doc @@ -118,10 +118,14 @@ '^u' Add an object with the current MRU values to that location, even if there is already another object of the same class at that location. +'ex' + Export a level (given the operating system command to receive the + exported data). See export.doc for details. + 'lc' Set the level code number. This is a 16-bit number which can be used in the class codes of your puzzle set for whatever purpose you wish; the game engine does not use this value itself. Index: default.heromeshrc ================================================================== --- default.heromeshrc +++ default.heromeshrc @@ -145,10 +145,11 @@ ?.editKey.ctrl.P: ^P ?.editKey.ctrl.Q: ^Q ?.editKey.ctrl.S: ^S ?.editKey.space: ^c ?.editKey.return: ^e +?.editKey.f2: select 'ex',:Export_Level; ?.editClick.left: ^a ?.editClick.alt.left: ^u ?.editClick.right: delete from objects where x=$X and y=$Y and up is null; ! Global key bindings Index: edit.c ================================================================== --- edit.c +++ edit.c @@ -692,10 +692,78 @@ objects[n]->misc1=m->misc1; objects[n]->misc2=m->misc2; objects[n]->misc3=m->misc3; pflink(n); } + +static void fprint_esc(FILE*fp,Uint8 c,const char*t) { + char isimg=0; + if(!c) return; + fputc(c,fp); + while(*t) switch(c=*t++) { + case 1 ... 8: fprintf(fp,"\\%c",c+'0'-1); break; + case 10: fprintf(fp,"\\n"); break; + case 11: fprintf(fp,"\\l"); break; + case 12: fprintf(fp,"\\c"); break; + case 14: fprintf(fp,"\\i"); isimg=1; break; + case 15: fprintf(fp,"\\b"); break; + case 16: fprintf(fp,"\\q"); break; + case 31: + if(!*t) break; + fprintf(fp,"\\x%02X",*t++); + break; + case 32 ... 127: + if(c=='\\') { + if(isimg) isimg=0; else fputc(c,fp); + } + fputc(c,fp); + break; + default: + fprintf(fp,"\\x%02X",c); + } + fputc('\n',fp); +} + +static void fprint_misc(FILE*fp,Value v) { + switch(v.t) { + case TY_NUMBER: fprintf(fp," %u",(int)v.u); break; + case TY_CLASS: fprintf(fp," $%s",classes[v.u]->name); break; + case TY_MESSAGE: fprintf(fp," %s%s",v.u<256?"":"#",v.u<256?standard_message_names[v.u]:messages[v.u-256]); + case TY_LEVELSTRING: fprintf(fp," %%%u",(int)v.u); break; + default: fprintf(fp," ???"); break; + } +} + +static void export_level(const char*cmd) { + int i; + Uint32 n; + Object*o; + FILE*fp; + if(!cmd) return; + fp=popen(cmd,"w"); + if(!fp) { + screen_message("Cannot open pipe"); + return; + } + fprintf(fp,"; Free Hero Mesh exported level ID=%d ORD=%d\n",level_id,level_ord); + fprint_esc(fp,'@',level_title); + fprintf(fp,"C %d\nD %d %d\n",level_code,pfwidth,pfheight); + for(i=0;i<64*64;i++) { + n=playfield[i]; + while(n!=VOIDLINK) { + o=objects[n]; + fprintf(fp,"%d %d $%s %d",o->x,o->y,classes[o->class]->name,o->image); + fprint_misc(fp,o->misc1); + fprint_misc(fp,o->misc2); + fprint_misc(fp,o->misc3); + fprintf(fp," %d\n",o->dir); + n=o->up; + } + } + for(i=0;i