Index: commandline.doc ================================================================== --- commandline.doc +++ commandline.doc @@ -34,12 +34,14 @@ used together with -C, -H, -L, -M to see how it is parsing it. -e Start in the editor instead of game. --n (not implemented yet) - Create a new puzzle set. +-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. -r Open in read-only mode. -t Index: edit.c ================================================================== --- edit.c +++ edit.c @@ -388,5 +388,23 @@ redraw_editor(); break; } } } + +void write_empty_level_set(FILE*fp) { + static const unsigned char d[]= + "CLASS.DEF\0\x00\x00\x02\x00" + "\x00\x00" // no classes or messages + "LEVEL.IDX\0\x00\x00\x02\x00" + "\x00\x00" // only one level + "0.LVL\0\x00\x00\x0D\x00" + "\x00\x00" // level version + "\x00\x00" // level code + "\x00\x00" // width/height + "Blank\0" // title + "\xFF" // objects + ; + fwrite(d,1,sizeof(d)-1,fp); + fflush(fp); + rewind(fp); +} Index: heromesh.h ================================================================== --- heromesh.h +++ heromesh.h @@ -245,6 +245,7 @@ void run_game(void); // == edit == void run_editor(void); +void write_empty_level_set(FILE*); Index: main.c ================================================================== --- main.c +++ main.c @@ -438,13 +438,13 @@ fprintf(stderr,"Initializing user cache...\n"); if(z=sqlite3_exec(userdb,"BEGIN;",0,0,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb)); if(z=sqlite3_prepare_v2(userdb,"SELECT `ID`, `TIME` FROM `USERCACHEINDEX` WHERE `NAME` = ?1;",-1,&st,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb)); nam1=sqlite3_mprintf("%s.level",basefilename); if(!nam1) fatal("Allocation failed\n"); - nam2=realpath(nam1,0); + nam2=main_options['n']?strdup(nam1):realpath(nam1,0); if(!nam2) fatal("Cannot find real path of '%s': %m\n",nam1); - levelfp=fopen(nam2,main_options['r']?"r":"r+"); + levelfp=fopen(nam2,main_options['n']?"w+x":main_options['r']?"r":"r+"); if(!levelfp) fatal("Cannot open '%s' for reading%s: %m\n",nam2,main_options['r']?"":"/writing"); sqlite3_free(nam1); sqlite3_bind_text(st,1,nam2,-1,0); z=sqlite3_step(st); if(z==SQLITE_ROW) { @@ -454,16 +454,17 @@ leveluc=t1=-1; } else { fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb)); } sqlite3_reset(st); + if(main_options['n']) write_empty_level_set(levelfp); nam1=sqlite3_mprintf("%s.solution",basefilename); if(!nam1) fatal("Allocation failed\n"); - nam3=realpath(nam1,0); + nam3=main_options['n']?strdup(nam1):realpath(nam1,0); if(!nam3) fatal("Cannot find real path of '%s': %m\n",nam1); if(!strcmp(nam2,nam3)) fatal("Level and solution files seem to be the same file\n"); - solutionfp=fopen(nam3,main_options['r']?"r":"r+"); + solutionfp=fopen(nam3,main_options['n']?"w+x":main_options['r']?"r":"r+"); if(!solutionfp) fatal("Cannot open '%s' for reading%s: %m\n",nam3,main_options['r']?"":"/writing"); sqlite3_free(nam1); sqlite3_bind_text(st,1,nam3,-1,0); z=sqlite3_step(st); if(z==SQLITE_ROW) { @@ -829,10 +830,14 @@ if(argc>optind && argv[1][0]=='=') { globalclassname=argv[optind++]+1; } else if(find_globalclassname()) { globalclassname=strrchr(basefilename,'/'); globalclassname=globalclassname?globalclassname+1:basefilename; + } + if(main_options['n']) { + if(main_options['r']) fatal("Switches -r and -n are conflicting\n"); + main_options['x']=1; } if(!main_options['c']) load_options(); if(argc>optind) read_options(argc-optind,argv+optind); *optionquery=xrm_make_quark(globalclassname,0)?:xrm_anyq; #ifdef __GNUC__ @@ -850,10 +855,11 @@ if(main_options['T']) { test_mode(); return 0; } init_usercache(); + if(main_options['n']) return 0; load_classes(); load_level_index(); optionquery[1]=Q_maxObjects; max_objects=strtoll(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,0)?:0xFFFF0000L; set_tracing();