Index: TODO ================================================================== --- TODO +++ TODO @@ -16,12 +16,10 @@ * Editor * Mouse dragging * Level index editor * Table of contents for levels (partially implemented) * Can define your own columns - * Update SOLVED (and SOLVABLE) column during playing - * Cache invalidation in editor * Can be divisions by sections * Deal better with allowing to skip past corrupted levels * Picture editor/loading * Allowing more altimages * Batch insert multiple dependent image lumps Index: edit.c ================================================================== --- edit.c +++ edit.c @@ -270,10 +270,15 @@ 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); + // This next line might fail if the LEVELS table has not been loaded yet. + // Attempting to drop it before it is loaded is slower than it should be, somehow. + // (I also suspect there might be a bug in SQLite, although I am unsure.) + // Therefore, it first tries to truncate it; if it hasn't been loaded, it fails. + sqlite3_exec(userdb,"DELETE FROM LEVELS; DROP TABLE TEMP.LEVELS;",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(); if(solution_data) { Index: function.c ================================================================== --- function.c +++ function.c @@ -1182,14 +1182,16 @@ .xFilter=vt1_playfield_filter, .xNext=vt1_playfield_next, ); static int vt1_levels_connect(sqlite3*db,void*aux,int argc,const char*const*argv,sqlite3_vtab**vt,char**err) { + if(levels_schema) goto declare; //TODO: Add columns specific to a puzzle set. levels_schema=sqlite3_mprintf("CREATE TEMPORARY TABLE `LEVELS`" "(`ID` INTEGER PRIMARY KEY, `ORD` INT, `CODE` INT, `WIDTH` INT, `HEIGHT` INT, `TITLE` BLOB, `SOLVED` INT, `SOLVABLE` INT);"); if(!levels_schema) fatal("Allocation failed\n"); + declare: sqlite3_declare_vtab(db,levels_schema); *vt=sqlite3_malloc(sizeof(sqlite3_vtab)); return *vt?SQLITE_OK:SQLITE_NOMEM; } @@ -1202,16 +1204,14 @@ int i,j; long n; int txn=sqlite3_get_autocommit(userdb)?sqlite3_exec(userdb,"BEGIN;",0,0,0):1; if(!levels_schema) return SQLITE_CORRUPT_VTAB; if(screen) set_cursor(XC_coffee_mug); - fprintf(stderr,"Loading level index...\n"); + fprintf(stderr,"Loading level table...\n"); if(sqlite3_exec(userdb,levels_schema,0,0,0)) { err: fatal("SQL error while loading LEVELS table: %s\n",sqlite3_errmsg(userdb)); } - sqlite3_free(levels_schema); - levels_schema=0; if(sqlite3_prepare_v2(userdb,"SELECT `LEVEL`, IFNULL(`DATA`,READ_LUMP_AT(`OFFSET`,?1)), `USERSTATE` FROM `USERCACHEDATA`" " WHERE `FILE` = LEVEL_CACHEID() AND `LEVEL` NOT NULL AND `LEVEL` >= 0 ORDER BY `LEVEL`;",-1,&st1,0)) goto err; // ?1=ID, ?2=CODE, ?3=WIDTH, ?4=HEIGHT, ?5=TITLE, ?6=SOLVED, ?7=SOLVABLE if(sqlite3_prepare_v3(userdb,"INSERT INTO `LEVELS` VALUES(?1,NULL,?2,?3,?4,?5,?6,?7);",-1,SQLITE_PREPARE_NO_VTAB,&st2,0)) Index: game.c ================================================================== --- game.c +++ game.c @@ -980,10 +980,11 @@ p+=8; } memcpy(p,replay_list,replay_pos); write_lump(FIL_SOLUTION,level_id,sz,data); free(data); + sqlite3_exec(userdb,"UPDATE `LEVELS` SET `SOLVABLE` = 1 WHERE `ID` = LEVEL_ID();",0,0,0); } void run_game(void) { int i; SDL_Event ev; @@ -1049,10 +1050,11 @@ inputs_count=0; if(saved_inserting) inserting=1,saved_inserting=0; no_dead_anim=0; if(gameover==1) { if(should_record_solution) record_solution(); + if(!solution_replay && !solved) sqlite3_exec(userdb,"UPDATE `LEVELS` SET `SOLVED` = 1 WHERE `ID` = LEVEL_ID();",0,0,0); if(autowin) do_autowin(); } } redraw_game(); timerflag=0; // ensure we have not missed a timer event