Index: bindings.doc ================================================================== --- bindings.doc +++ bindings.doc @@ -99,10 +99,15 @@ will receive the move list (in the same format as above) on stdin. === Editor commands === +'^N' + Add a new level (after the last one). The new level has the same + dimensions as the current level, but contains no objects or strings, + and the title is set to "New Level". + '^S' Save level. '^a' <location> Add an object with the current MRU values to that location, if there Index: default.heromeshrc ================================================================== --- default.heromeshrc +++ default.heromeshrc @@ -139,14 +139,15 @@ ?.editKey.up: select 'mR',-1; ?.editKey.down: select 'mR',+1; ?.editKey.C: select 'lc',:level_code where :level_code=cast(:level_code as int); ?.editKey.F: with n(n) as (select 65 union all select n+1 h from n where h<=64*pfheight()+65) select '^a',n from n; ?.editKey.R: select 're',substr(:resize,1,instr(:resize,'x')-1),substr(:resize,instr(:resize,'x')+1) where length(:resize); -?.editKey.ctrl.X: select 're',pfwidth(),pfheight(); +?.editKey.ctrl.N: ^N ?.editKey.ctrl.P: ^P ?.editKey.ctrl.Q: ^Q ?.editKey.ctrl.S: ^S +?.editKey.ctrl.X: select 're',pfwidth(),pfheight(); ?.editKey.space: ^c ?.editKey.return: ^e ?.editKey.f1: select 'im',:Import_Level; ?.editKey.f2: select 'ex',:Export_Level; ?.editClick.left: ^a Index: edit.c ================================================================== --- edit.c +++ edit.c @@ -167,10 +167,25 @@ sqlite3_str_appendchar(s,1,o->misc3.u&0xFF); sqlite3_str_appendchar(s,1,o->misc3.u>>8); } } } + +static void update_level_index(void) { + Uint8*data; + int i; + if(level_ord>level_nindex) { + level_index=realloc(level_index,++level_nindex*sizeof(Uint16)); + if(!level_index) fatal("Allocation failed\n"); + level_index[level_ord-1]=level_id; + } + data=malloc(level_nindex<<1); + if(!data) fatal("Allocation failed\n"); + for(i=0;i<level_nindex;i++) data[i+i]=level_index[i]&255,data[i+i+1]=level_index[i]>>8; + write_lump(FIL_LEVEL,LUMP_LEVEL_IDX,2*level_nindex,data); + free(data); +} static void save_level(void) { /* Format of objects: * bit flags (or 0xFF for end): @@ -228,13 +243,16 @@ // Done sz=sqlite3_str_length(str); if(i=sqlite3_str_errcode(str)) fatal("SQL string error (%d)\n",i); data=sqlite3_str_finish(str); if(!data) fatal("Allocation failed\n"); + sqlite3_exec(userdb,"BEGIN;",0,0,0); write_lump(FIL_LEVEL,level_id,sz,data); sqlite3_free(data); + if(level_ord==level_nindex+1) update_level_index(); rewrite_class_def(); + sqlite3_exec(userdb,"COMMIT;",0,0,0); } static void redraw_editor(void) { char buf[32]; SDL_Rect r; @@ -972,10 +990,35 @@ done: free(buf); pclose(fp); generation_number_inc=0; } + +static void new_level(void) { + sqlite3_stmt*st; + int i; + if(i=sqlite3_prepare_v2(userdb,"SELECT COALESCE(MAX(`LEVEL`),-1)+1 FROM `USERCACHEDATA` WHERE `FILE` = LEVEL_CACHEID();",-1,&st,0)) { + screen_message(sqlite3_errmsg(userdb)); + return; + } + i=sqlite3_step(st); + if(i!=SQLITE_ROW) { + sqlite3_finalize(st); + screen_message(sqlite3_errmsg(userdb)); + return; + } + i=sqlite3_column_int(st,0); + sqlite3_finalize(st); + if(i>0xFFFE) return; + annihilate(); + level_id=i; + free(level_title); + level_title=strdup("New Level"); + if(!level_title) fatal("Allocation failed\n"); + level_changed=level_version=level_code=0; + level_ord=level_nindex+1; +} static int editor_command(int prev,int cmd,int number,int argc,sqlite3_stmt*args,void*aux) { int x,y; switch(cmd) { case '^a': // Add object (no duplicates) @@ -990,10 +1033,14 @@ return 0; case '^u': // Add object (allow duplicates) if(prev) return prev; add_object_at(number&63?:64,number/64?:64,mru+curmru,0); return 0; + case '^N': // New level + if(level_nindex>0xFFFE) return 0; + new_level(); + return 1; case '^P': // Play return -2; case '^Q': // Quit return -1; case '^S': // Save level