Index: TODO ================================================================== --- TODO +++ TODO @@ -32,11 +32,11 @@ * Figure out why the $SeekerCloser class doesn't seem to work properly * Level 232 of SUPERHRO puzzle set (the Lava shouldn't expand? why?) * Animation stopping unexpectedly (until a key is pushed) * Display solution comments/timestamp * VCR mode -* Command-line switch for batch import/export levels +* Command-line switch for batch export levels * SQL * Implement the GROUP column in the CLASSES table * Allow multiple SQL statements in one binding * Fonts/text * More code pages Index: commandline.doc ================================================================== --- commandline.doc +++ commandline.doc @@ -42,10 +42,15 @@ -h Disable portable mode; always use the HOME environment variable to find the configuration and database files. +-i + Batch import levels. Accepts the level import format (see export.doc) + from stdin. It will not overwrite existing levels unless the existing + level is blank, in which case it will overwrite it. + -n Create a new puzzle set. The .xclass and .class files should already exist; the .level and .solution files should not already exist, and will be created with minimal data. Index: edit.c ================================================================== --- edit.c +++ edit.c @@ -992,11 +992,11 @@ char*buf=0; char*p; sqlite3_str*sol=0; Value v; if(!cmd || !*cmd) return; - fp=popen(cmd,"r"); + fp=main_options['i']?stdin:popen(cmd,"r"); if(!fp) { screen_message("Cannot open pipe"); return; } discard_solution(); @@ -1008,18 +1008,20 @@ switch(*p) { case '0' ... '9': if(!d) { missd: screen_message("Missing D line"); + if(main_options['i']) exit(1); goto done; } p=import_numbers(p,&x,&y); if(!p) goto bad; if(x<1 || x>pfwidth || y<1 || y>pfheight) { range: fprintf(stderr,"Imported level coordinates out of range: %d %d\n",x,y); screen_message("Coordinates out of range"); + if(main_options['i']) exit(1); goto done; } p=import_value(p,&v); if(!p || v.t!=TY_CLASS) goto bad; v.u=objalloc(v.u); @@ -1100,22 +1102,26 @@ break; } } if(x==256) goto bad; break; + case '=': + if(main_options['i']) goto done; + // fall through default: if(*p && *p!=';') { bad: fprintf(stderr,"Invalid record in imported data: %s\n",buf); + if(main_options['i']) exit(1); screen_message("Invalid record"); goto done; } } } done: free(buf); - pclose(fp); + if(!main_options['i']) pclose(fp); generation_number_inc=0; if(sol) { solution_length=sqlite3_str_length(sol); solution_data=sqlite3_str_finish(sol); if(!solution_data) fatal("Allocation failed"); @@ -1708,5 +1714,18 @@ ; fwrite(d,1,sizeof(d)-1,fp); fflush(fp); rewind(fp); } + +void batch_import(void) { + load_level(level_id); + if(nobjects) new_level(); + while(!feof(stdin)) { + if(main_options['v']) fprintf(stderr,"Level %d\n",level_ord); + import_level("#"); + if(nobjects) { + save_level(); + if(!feof(stdin)) new_level(); + } + } +} Index: export.doc ================================================================== --- export.doc +++ export.doc @@ -65,10 +65,13 @@ overwrite the existing solution when this level is saved. (Note: This does not automatically verify the solution; it only records it.) (Currently, this line is implemented only for import, and not for export. Later an option might be added to do this on export, too.) += + Delimiter between levels; only allowed in batch import mode. + === Misc values === A number is written in decimal, and must be 0 to 65535. Index: heromesh.h ================================================================== --- heromesh.h +++ heromesh.h @@ -303,10 +303,11 @@ extern EditorRect editrect; void run_editor(void); void write_empty_level_set(FILE*); +void batch_import(void); // == picedit == void run_picture_editor(void); Index: main.c ================================================================== --- main.c +++ main.c @@ -786,11 +786,11 @@ Uint32 n=0; SDLKey k; SDL_Event ev; char buf[32]; const UserCommand*uc; - int i; + int i,j; set_cursor(XC_tcross); SDL_LockSurface(screen); draw_text(0,0,"Hello, World!",0xF0,0xFF); buf[16]=0; for(i=0;i<16;i++) { @@ -825,10 +825,19 @@ n=1; goto keytest; case SDLK_g: n=0; goto keytest; + case SDLK_i: + SDL_FillRect(screen,0,5); + for(i=j=0;;i++) { + if(picture_size*(i+1)>screen->w) i=0,j++; + if(picture_size*(j+1)>screen->h) break; + draw_picture(picture_size*i,picture_size*j,n++); + } + SDL_Flip(screen); + break; case SDLK_p: sqlite3_exec(userdb,"SELECT * FROM `PICTURES`;",test_sql_callback,0,0); break; case SDLK_q: exit(0); @@ -1037,12 +1046,13 @@ } if(main_options['z']) { if(main_options['p'] || main_options['f'] || main_options['e']) fatal("Switches are conflicting with -z\n"); main_options['r']=1; } - if(main_options['n']) { - if(main_options['r']) fatal("Switches -r and -n are conflicting\n"); + if(main_options['n'] && main_options['i']) fatal("Switches -n and -i are conflicting\n"); + if(main_options['n'] || main_options['i']) { + if(main_options['r']) fatal("Switches -r and -%c are conflicting\n",main_options['i']?'i':'n'); main_options['x']=1; } if(main_options['a']) main_options['r']=main_options['x']=1; if(main_options['p']) main_options['r']=1; if(main_options['f']) main_options['x']=1; @@ -1089,11 +1099,15 @@ } optionquery[1]=Q_maxTrigger; max_trigger=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,10); if(main_options['a']) run_auto_test(); if(main_options['x']) { - if(main_options['f']) { + if(main_options['i']) { + batch_import(); + if(main_options['f']) flush_usercache(); + return 0; + } else if(main_options['f']) { if(main_options['r']) fatal("Cannot flush user cache; puzzle set is read-only\n"); flush_usercache(); return 0; } fprintf(stderr,"Ready for executing SQL statements.\n"); Index: man6/heromesh.6 ================================================================== --- man6/heromesh.6 +++ man6/heromesh.6 @@ -32,10 +32,13 @@ .IP -f Only flush the user cache and then terminate. .IP -h Disable portable mode; always use the HOME environment variable to find the files. +.IP -i +Batch import levels. +Accepts the level data (in the export format) from stdin. .IP -n Create a new puzzle set. The class definition file and image set must already exist. .IP -p Start the picture editor.