Index: game.c ================================================================== --- game.c +++ game.c @@ -193,16 +193,45 @@ SDL_LockSurface(screen); draw_text(0,40,buf,0xF0,0xF1); SDL_UnlockSurface(screen); SDL_Flip(screen); } + +static void end_level(void) { + long sz=replay_size; + if(!replay_list) return; + if(sz0xFFFF?0xFFFF:sz); + } + sz=replay_count+4; + replay_list[sz-4]=replay_mark>>8; + replay_list[sz-3]=replay_mark; + replay_list[sz-2]=replay_count>>8; + replay_list[sz-1]=replay_count; + write_userstate(FIL_LEVEL,level_id,sz,replay_list); +} static void begin_level(int id) { const char*t; + long sz; + if(replay_count) end_level(); inputs_count=0; replay_pos=0; t=load_level(id)?:init_level(); + free(replay_list); + replay_list=read_userstate(FIL_LEVEL,level_id,&sz); + if(sz>=2) { + replay_size=(sz>0xFFFF?0xFFFF:sz); + replay_count=(replay_list[sz-2]<<8)|replay_list[sz-1]; + if(sz-replay_count>=4) replay_mark=(replay_list[replay_count]<<8)|replay_list[replay_count+1]; else replay_mark=0; + } else { + replay_count=replay_mark=replay_size=0; + free(replay_list); + replay_list=0; + } if(t) { gameover=-1; screen_message(t); } else { gameover=0; @@ -559,10 +588,12 @@ gameover=-1; return; } if(!key_ignored) { if(replay_pos>=replay_size) { + if(replay_size>0xFDFF) replay_size=0xFDFF; + if(replay_size+0x200<=replay_pos) fatal("Confusion in input_move function\n"); replay_list=realloc(replay_list,replay_size+=0x200); if(!replay_list) fatal("Allocation failed\n"); } replay_list[replay_pos++]=k; if(replay_pos>replay_count) replay_count=replay_pos; @@ -582,11 +613,11 @@ switch(ev.type) { case SDL_VIDEOEXPOSE: redraw_game(); break; case SDL_QUIT: - exit(0); + goto quit; break; case SDL_MOUSEMOTION: show_mouse_xy(&ev); break; case SDL_USEREVENT: @@ -611,11 +642,11 @@ goto command; } case SDL_KEYDOWN: i=exec_key_binding(&ev,0,0,0,game_command,0); command: - if(i==-1) exit(0); + if(i==-1) goto quit; if(i==-2) { main_options['e']=1; SDL_SetTimer(0,0); return; } @@ -628,10 +659,13 @@ redraw_game(); timerflag=0; // ensure we have not missed a timer event break; } } + quit: + end_level(); + exit(0); } void locate_me(int x,int y) { Uint8 c=7; SDL_Rect r,rh,rv; Index: main.c ================================================================== --- main.c +++ main.c @@ -509,11 +509,11 @@ if(fst.st_mtime>t1 || fst.st_ctime>t1) leveluc=reset_usercache(levelfp,nam2,&fst,".LVL"); if(stat(nam3,&fst)) fatal("Unable to stat '%s': %m\n",nam3); if(fst.st_mtime>t2 || fst.st_ctime>t2) solutionuc=reset_usercache(solutionfp,nam3,&fst,".SOL"); free(nam2); free(nam3); - if(z=sqlite3_prepare_v3(userdb,"SELECT `OFFSET`, CASE WHEN ?3 THEN `DATA` ELSE `USERSTATE` END " + if(z=sqlite3_prepare_v3(userdb,"SELECT `OFFSET`, CASE WHEN ?3 THEN `USERSTATE` ELSE `DATA` END " "FROM `USERCACHEDATA` WHERE `FILE` = ?1 AND `LEVEL` = ?2;",-1,SQLITE_PREPARE_PERSISTENT,&readusercachest,0)) { fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb)); } if(z=sqlite3_exec(userdb,"COMMIT;",0,0,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb)); fprintf(stderr,"Done\n");