Index: bindings.doc ================================================================== --- bindings.doc +++ bindings.doc @@ -81,10 +81,22 @@ List objects at the specified coordinates, to examine their values. '^s' Toggle solution replay. +'mi' + Import a move list. The argument is a operating system command, that + when executed will write the move list to stdout, with one byte per + move (the Hero Mesh key codes). + +'ml' + Load a move list from a SQL blob. + +'mx' + Export a move list. The argument is a operating system command that + will receive the move list (in the same format as above) on stdin. + === Editor commands === '^c' Display the class selection menu. Index: game.c ================================================================== --- game.c +++ game.c @@ -511,10 +511,51 @@ s=sqlite3_mprintf("\x0C\x0E%s:%d\\ %s\x0B\x0F%s",classes[objects[n]->class]->name,objects[n]->image,classes[objects[n]->class]->name,classes[objects[n]->class]->gamehelp); if(!s) fatal("Allocation failed\n"); modal_draw_popup(s); sqlite3_free(s); } + +static void do_import_moves(const char*arg) { + FILE*fp; + int i; + if(!arg || !arg[strspn(arg," \t")]) return; + fp=popen(arg,"r"); + if(!fp) { + screen_message("Unable to open pipe for reading"); + return; + } + replay_list=realloc(replay_list,0x10000); + if(!replay_list) fatal("Allocation failed"); + replay_mark=0; + replay_size=0xFFFF; + i=fread(replay_list,1,0xFFFD,fp); + if(i&~0xFFFF) i=0; + replay_count=i; + pclose(fp); +} + +static void do_export_moves(const char*arg) { + FILE*fp; + int i; + if(!arg || !arg[strspn(arg," \t")]) return; + fp=popen(arg,"w"); + if(!fp) { + screen_message("Unable to open pipe for writing"); + return; + } + if(replay_count) fwrite(replay_list,1,replay_count,fp); + pclose(fp); +} + +static void do_load_moves(sqlite3_stmt*st) { + int i=sqlite3_column_bytes(st,1); + if(i&~0xFFFF) return; + if(replay_size