#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "globals.h" #include "temp_storage.h" #include #include #define STATE_CUR_VER 2 #define _GAME_ST "_GAME.TMP" #define _GLOBAL_ST "_GLOBEV.TMP" #define _SLOT_SAV "slot%02d.SAV" #define SLOTS_MAX 10 #define GM_MAPENABLE 0x1 #define SAVE_SLOT_S 34 #define LOAD_SLOT_S (372+34) #define SAVE_SLOT_E (34+203) #define LOAD_SLOT_E (372+34+203) #define SSAVE_VERSION 0 static TMPFILE_WR *story=NULL; static char load_another; char reset_mobiles=0; typedef struct s_save { int viewsector; char viewdir; short version; char not_used; int gold; short cur_group; char autosave; char enable_sort; char shownames; char showlives; char zoom_speed; char turn_speed; char autoattack; char music_vol; char sample_vol; char xbass; char bass; char treble; char stereing; char swapchans; char out_filter; int32_t glob_flags; int32_t game_time; char runes[5]; char level_name[13]; short picks; //pocet_sebranych predmetu v mysi short items_added; //pocet_pridanych predmetu int sleep_long; int game_flags; }S_SAVE; static int get_list_count(); static int unable_open_temp(char *c) { char d[]="Unable to open the file : ",*e; concat(e,d,c); closemode(); display_error(e); SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c); exit(1); } static void unable_write_temp(char *c) { char d[]="Unable to write to the temp file : ",*e; concat(e,d,c); closemode(); display_error(e); SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c); exit(1); } int load_org_map(char *filename,TSTENA **sides,TSECTOR **sectors,TMAP_EDIT_INFO **coords,int *mapsize) { FILE *f; void *temp; int sect; int32_t size,r; char nmapend=1; const char *c=build_pathname(2, gpathtable[SR_MAP],filename); f=fopen_icase(c,"rb"); if (f==NULL) return -1; do { r=load_section(f,&temp,§,&size); if (r==size) switch (sect) { case A_SIDEMAP: *sides=temp; break; case A_SECTMAP: *sectors=temp; if (mapsize!=NULL) *mapsize=size/sizeof(TSECTOR); break; case A_MAPINFO: if (coords!=NULL) *coords=temp;else free(temp); break; case A_MAPGLOB: //memcpy(&mglob,temp,min(sizeof(mglob),size)); free(temp); break; case A_MAPEND : nmapend=0; free(temp); break; default: free(temp); } else { if (temp!=NULL)free(temp); fclose(f); return -1; } } while (nmapend); fclose(f); return 0; } void save_daction(TMPFILE_WR *f,int count,D_ACTION *ptr) { if (ptr!=NULL) { save_daction(f,count+1,ptr->next); temp_storage_write(ptr,sizeof(D_ACTION),f); } else temp_storage_write(&count,2,f); } void load_daction(TMPFILE_RD *fsta) { uint16_t i,j; i=0; while (d_action!=NULL) //vymaz pripadne delaited actions { D_ACTION *p; p=d_action; d_action=p->next;free(p); } temp_storage_read(&i,2,fsta);d_action=NULL; for(j=0;jnext=d_action; d_action=p; } } void save_items(TMPFILE_WR *f) { int32_t i,j; short *c; for(i=0;ivyk_max) return -2; temp_storage_read(map_vyk,vyk_max*sizeof(TVYKLENEK),fsta); } return 0; } void save_all_fly(TMPFILE_WR *fsta) { LETICI_VEC *f; int32_t sz = 1; f=letici_veci; while (f!=NULL) { short *c; sz = sizeof(*f); temp_storage_write(&sz,sizeof(sz),fsta); temp_storage_write(f,sz,fsta); c=f->items; if (c!=NULL) do temp_storage_write(c,1*2,fsta); while (*c++); f=f->next; } sz = 0; temp_storage_write(&sz,sizeof(sz),fsta); } int load_all_fly(TMPFILE_RD *fsta) { LETICI_VEC *n; int32_t sz; destroy_all_fly(); temp_storage_read(&sz,sizeof(sz),fsta); while (sz == sizeof(LETICI_VEC)) { short items[100],*c; n=New(LETICI_VEC); c=items;memset(items,0,sizeof(items)); if (temp_storage_read(n,1*sizeof(*n),fsta)!=sizeof(*n)) { free(n); return -2; } if (n->items!=NULL) { do temp_storage_read(c,2,fsta); while (*c++); n->items=NewArr(short,c-items); memcpy(n->items,items,(c-items)*sizeof(short)); } add_fly(n); temp_storage_read(&sz,sizeof(sz),fsta); } return sz != 0; } int save_map_state() //uklada stav mapy pro savegame (neuklada aktualni pozici); { char sta[200]; char *bf = NULL; TMPFILE_WR *fsta; int32_t i; int32_t siz; TSTENA *org_sides; TSECTOR *org_sectors; short res=-1; unsigned char ver=0; strcpy(sta,level_fname); fsta=temp_storage_create(sta);if (fsta==NULL) unable_open_temp(sta); SEND_LOG("(SAVELOAD) Saving map state for current map"); if (load_org_map(level_fname,&org_sides,&org_sectors,NULL,NULL)) goto err; siz=(mapsize+7)/8; bf=(char *)getmem(siz); ver=STATE_CUR_VER; temp_storage_write(&ver,sizeof(ver)*1,fsta); //<------------------------- temp_storage_write(&mapsize,sizeof(mapsize)*1,fsta); //<------------------------- memset(bf,0,siz); temp_storage_write(&siz,1*sizeof(siz),fsta); //<------------------------- for(i=0;i>3]|=1<<(i & 7); temp_storage_write(bf,siz*1,fsta); for(i=0;i>3]|=1<<(i & 7); temp_storage_write(bf,siz*1,fsta); save_map_description(fsta); for(i=0;iSTATE_CUR_VER) goto err; if (!temp_storage_read(&i,sizeof(mapsize)*1,fsta)) goto err; if (mapsize!=i) goto err; SEND_LOG("(SAVELOAD) Loading map state for current map"); temp_storage_read(&siz,1*sizeof(siz),fsta); bf=(char *)getmem(siz); if (!temp_storage_read(bf,siz*1,fsta)) goto err; for (i=0;i>3]>>(i & 7)) & 1) map_coord[i].flags|=MC_AUTOMAP; if (!temp_storage_read(bf,siz*1,fsta)) goto err; for (i=0;i>3]>>(i & 7)) & 1) map_coord[i].flags|=MC_DISCLOSED; load_map_description(fsta); while (temp_storage_read(&i,sizeof(i),fsta) && i >= 0 && i<=mapsize*4) if (temp_storage_read(map_sides+i,1*sizeof(TSTENA),fsta)!=sizeof(TSTENA)) goto err; while (temp_storage_read(&i,sizeof(i),fsta) && i >= 0 && i<=mapsize) if (temp_storage_read(map_sectors+i,1*sizeof(TSECTOR),fsta)!=sizeof(TSECTOR)) goto err; if (reset_mobiles) //reloads mobiles if flag present { char mm[MAX_MOBS]; for(i=0;i=0 && i<=MAX_MOBS) if (temp_storage_read(mobs+i,1*sizeof(TMOB),fsta)!=sizeof(TMOB)) goto err; } for(i=0;i 255) name_size_b = 255; else name_size_b = (uint8_t)name_size; fwrite(&name_size_b,1,1,f); fwrite(name, 1, name_size_b, f); uint32_t data_size = sz; fwrite(&data_size,1,sizeof(data_size),f); fwrite(data, 1,data_size, f); } static void pack_status_file_cb(const char *name, void *ctx) { FILE *f = ctx; int32_t sz = temp_storage_find(name); assert(sz > 0); void *data = getmem(sz); temp_storage_retrieve(name, data, sz); add_status_file(f, name, sz, data); free(data); } int pack_all_status(FILE *f) { char c = 0; temp_storage_list(pack_status_file_cb, f); fwrite(&c,1,1,f); return 0; } typedef enum enum_all_status_callback_result_t { enum_status_cont_skip, //continue, skip this block enum_status_cont_read, //continue, i read this block enum_status_skip_stop, //stop, skip this block enum_status_read_stop, //stop, don't skip i read this block enum_status_error //error } ENUM_ALL_STATUS_CALLBACK_RESULT; //return 1 success, 0 stopped, -1 error static int enum_all_status(FILE *f, ENUM_ALL_STATUS_CALLBACK_RESULT (*cb)(FILE *, const char *, size_t , void *), void *ctx) { while(1) { uint8_t name_size_b; if (fread(&name_size_b, 1,1,f)==0) return 1; char *name = (char *)alloca(name_size_b+1); if (fread(name, 1, name_size_b, f) != name_size_b) return -1; name[name_size_b] = 0; uint32_t data_size; if (fread(&data_size,1,sizeof(uint32_t),f) != sizeof(uint32_t)) return -1; ENUM_ALL_STATUS_CALLBACK_RESULT st = cb(f, name, data_size, ctx); switch (st) { case enum_status_error: return 0; case enum_status_cont_skip: fseek(f, data_size, SEEK_CUR);break; case enum_status_cont_read: break; case enum_status_skip_stop: fseek(f, data_size, SEEK_CUR);return 0; case enum_status_read_stop: return 0; } } } static ENUM_ALL_STATUS_CALLBACK_RESULT unpack_status_callback(FILE *f, const char *name, size_t datasize, void *_) { void *buff = getmem(datasize); if (fread(buff, 1, datasize, f) != datasize) { free(buff); return enum_status_error;; } temp_storage_store(name, buff, datasize); free(buff); return enum_status_cont_read; } int unpack_all_status(FILE *f) { int r = enum_all_status(f, &unpack_status_callback, NULL); if (r) return 0; return -1; } int save_basic_info() { TMPFILE_WR *f; S_SAVE s; short *p; int i; char res=0; THUMAN *h; SEND_LOG("(SAVELOAD) Saving basic info for game (file:%s)",_GAME_ST ); f=temp_storage_create(_GAME_ST); if (f==NULL) return 1; s.viewsector=viewsector; s.viewdir=viewdir; s.version=SSAVE_VERSION; s.not_used=0; s.gold=money; s.cur_group=cur_group; s.shownames=show_names; s.showlives=show_lives; s.autoattack=autoattack; s.turn_speed=turn_speed(-1); s.zoom_speed=zoom_speed(-1); s.game_time=game_time; s.enable_sort=enable_sort; s.sleep_long=sleep_ticks; s.sample_vol=get_snd_effect(SND_GFX); s.music_vol=get_snd_effect(SND_MUSIC); s.xbass=get_snd_effect(SND_XBASS); s.bass=get_snd_effect(SND_BASS); s.treble=get_snd_effect(SND_TREBL); s.stereing=get_snd_effect(SND_LSWAP); s.swapchans=get_snd_effect(SND_SWAP); s.out_filter=get_snd_effect(SND_OUTFILTER); s.autosave=autosave_enabled; s.game_flags=(enable_glmap!=0); strcopy_n(s.level_name,level_fname,sizeof(s.level_name)); for(i=0;i<5;i++) s.runes[i]=runes[i]; if (picked_item!=NULL) for(i=1,p=picked_item;*p;i++,p++);else i=0; s.picks=i; s.items_added=item_count-it_count_orgn; temp_storage_write(&s,1*sizeof(s),f); if (i) temp_storage_write(picked_item,2*i,f); if (s.items_added) temp_storage_write(glob_items+it_count_orgn,sizeof(TITEM)*s.items_added,f); save_spells(f); temp_storage_write(postavy,1*sizeof(postavy),f); for(i=0,h=postavy;idemon_save!=NULL) temp_storage_write(h->demon_save,sizeof(THUMAN)*1,f); //ulozeni polozek s demony res|=save_dialog_info(f); temp_storage_close_wr(f); SEND_LOG("(SAVELOAD) Done... Result: %d",res); return res; } int load_basic_info() { TMPFILE_RD *f; S_SAVE s; int i; char res=0; TITEM *itg; THUMAN *h; SEND_LOG("(SAVELOAD) Loading basic info for game (file:%s)",_GAME_ST); f=temp_storage_open(_GAME_ST); if (f==NULL) return 1; res|=(temp_storage_read(&s,1*sizeof(s),f)!=sizeof(s)); if (s.game_flags & GM_MAPENABLE) enable_glmap=1;else enable_glmap=0; i=s.picks; if (picked_item!=NULL) free(picked_item); if (i) { picked_item=NewArr(short,i); res|=(temp_storage_read(picked_item,2*i,f)!=(unsigned)i); } else picked_item=NULL; itg=NewArr(TITEM,it_count_orgn+s.items_added); memcpy(itg,glob_items,it_count_orgn*sizeof(TITEM)); free(glob_items);glob_items=itg; if (s.items_added) res|=(temp_storage_read(glob_items+it_count_orgn,sizeof(TITEM)*s.items_added,f)!=(unsigned)s.items_added); item_count=it_count_orgn+s.items_added; res|=load_spells(f); for(i=0,h=postavy;idemon_save!=NULL) free(h->demon_save); if (!res) res|=(temp_storage_read(postavy,1*sizeof(postavy),f)!=sizeof(postavy)); for(i=0,h=postavy;iprogramovano=0; h->provadena_akce=h->zvolene_akce=NULL; h->dostal=0; if (h->demon_save!=NULL) { h->demon_save=New(THUMAN); temp_storage_read(h->demon_save,sizeof(THUMAN)*1,f);//obnova polozek s demony } } res|=load_dialog_info(f); temp_storage_close_rd(f); viewsector=s.viewsector; viewdir=s.viewdir; cur_group=s.cur_group; show_names=s.shownames; show_lives=s.showlives; autoattack=s.autoattack; turn_speed(s.turn_speed); zoom_speed(s.zoom_speed); game_time=s.game_time; sleep_ticks=s.sleep_long; enable_sort=s.enable_sort; autosave_enabled=s.autosave; money=s.gold; for(i=0;i<5;i++) runes[i]=s.runes[i]; set_snd_effect(SND_GFX,s.sample_vol); set_snd_effect(SND_MUSIC,s.music_vol); set_snd_effect(SND_XBASS,s.xbass); set_snd_effect(SND_BASS,s.bass); set_snd_effect(SND_TREBL,s.treble); set_snd_effect(SND_LSWAP,s.stereing); set_snd_effect(SND_SWAP,s.swapchans); set_snd_effect(SND_OUTFILTER,s.out_filter); if (level_fname==NULL || strcmp(s.level_name,level_fname)) { strcopy_n(loadlevel.name,s.level_name,sizeof(loadlevel.name)); loadlevel.start_pos=viewsector; loadlevel.dir=viewdir; send_message(E_CLOSE_MAP); load_another=1; } else load_another=0; for(i=0;i0) { SEND_LOG("(ERROR) Error detected during unpacking game... Loading stopped (result:%d)",r); return r; } load_book(); load_global_events(); if ((t=load_saved_shops())!=0) return t; if ((t=load_basic_info())!=0) return t; running_battle=0; norefresh=0; if (!load_another) restore_current_map(); else { save_map=0; norefresh=1; } for(t=0;tname) == 0) { void *d = getmem(datasize); if (fread(d, 1, datasize, f) != datasize) { free(d); return enum_status_error; } me->size = datasize; me->data = d; return enum_status_read_stop; } else { return enum_status_cont_skip; } } static void load_specific_file(int slot_num,char *filename,void **out,int32_t *size) //call it in task! { FILE *slot; char *d; const char *c = build_pathname(2, gpathtable[SR_SAVES], _SLOT_SAV); d=alloca(strlen(c)+6); sprintf(d,c,slot_num); slot=fopen_icase(d,"rb"); if (slot==NULL) { *out=NULL; return; } fseek(slot,SAVE_NAME_SIZE,SEEK_CUR); LOAD_SPECIFIC_FILE_CALLBACK_DATA ctx; ctx.name = filename; *out = NULL; *size = 0; if (enum_all_status(slot, &load_specific_file_callback, &ctx) == 0){ *out = ctx.data; *size = ctx.size; } fclose(slot); } //------------------------ SAVE LOAD DIALOG ---------------------------- static char force_save; static TSTR_LIST slot_list=NULL; static int last_select=-1; static char used_pos[SLOTS_MAX]; static TSTR_LIST story_text=NULL; static void *back_texture=NULL; static int cur_story_pos=0; static char load_mode; #define SLOT_SPACE 33 #define SELECT_COLOR (RGB555(31,31,31)|FONT_TSHADOW) #define NORMAL_COLOR (RGB555(12,31,12)|FONT_TSHADOW) #define STORY_X 57 #define STORY_Y 50 #define STORY_XS (298-57) #define STORY_YS (302-50) void read_slot_list() { int i; char *name; char slotname[SAVE_NAME_SIZE]; if (slot_list==NULL) slot_list=create_list(SLOTS_MAX); const char *mask = build_pathname(2, gpathtable[SR_SAVES],_SLOT_SAV); name=alloca(strlen(mask)+1); for(i=0;i0) { int xs,ys; d=c; while (size>0 && *d!='\r' && *d!='\n') {d++;size--;}; if (!size) break; *d=0; { char *e,*or; or=e=getmem(strlen(c)+2); zalamovani(c,e,STORY_XS,&xs,&ys); while (*e) { str_add(&ls,e); if (text_width(e)>STORY_XS) abort(); e=strchr(e,0)+1; } c=d+1;size--; if (size > 0 &&(*c=='\n' || *c=='\r')) {c++;size--;}; free(or); } } free(text_data); } else ls=NULL; if (story_text!=NULL) release_list(story_text); story_text=ls; cur_story_pos=get_list_count();if (cur_story_pos<0) cur_story_pos=0; redraw_story_bar(cur_story_pos); } static void read_story(int slot) { static int task_num=-1; if (task_num!=-1) term_task(task_num); if (slot!=-1) task_num=add_task(8196,read_story_task,slot); } static int get_list_count() { int count,i,max=0; if (story_text==NULL) return 0; count=str_count(story_text); for(i=0;i0) { if (id!=last_select) { set_font(H_FBOLD,NORMAL_COLOR); if (last_select!=-1) place_name(force_save,last_select,1); set_font(H_FBOLD,SELECT_COLOR); place_name(force_save,id,1); last_select=id; read_story(id); } } else id=-1; return id; } char updown_scroll(int id,int xa,int ya,int xr,int yr); static char updown_noinst=0; static void updown_scroll_hold(EVENT_MSG *msg,void **_) { if (msg->msg == E_MOUSE) { MS_EVENT *ms; ms=get_mouse(msg); if (ms->event_type==0x4 || !ms->tl1 || ms->tl2 || ms->tl3) { send_message(E_DONE,E_MOUSE,updown_scroll_hold); send_message(E_DONE,E_TIMER,updown_scroll_hold); updown_noinst=0; } } if (msg->msg == E_TIMER) { MS_EVENT *ms; updown_noinst=1; ms=&ms_last_event; ms->event_type=0x2; send_message(E_MOUSE,ms); if (updown_noinst) { send_message(E_DONE,E_MOUSE,updown_scroll_hold); send_message(E_DONE,E_TIMER,updown_scroll_hold); updown_noinst=0; } else updown_noinst=1; } } char updown_scroll(int id,int xa,int ya,int xr,int yr) { int count; xr,yr,xa,ya; if (story_text==NULL) return 0; cur_story_pos+=id; count=get_list_count(); if (cur_story_pos>count) cur_story_pos=count; if (cur_story_pos<0) cur_story_pos=0; redraw_story_bar(cur_story_pos); if (updown_noinst) { updown_noinst=0; return 1; } send_message(E_ADD,E_MOUSE,updown_scroll_hold); send_message(E_ADD,E_TIMER,updown_scroll_hold); return 1; } static char close_saveload(int id,int xa,int ya,int xr,int yr) { xa;ya;xr;yr;id; if (ms_last_event.event_type & 0x8) { unwire_proc(); wire_proc(); } return 1; } char clk_load_konec(int id,int xa,int ya,int xr,int yr) { id;xa;ya;xr;yr; send_message(E_CLOSE_MAP,-1); return 1; } static char clk_load_proc(int id,int xa,int ya,int xr,int yr); #define CLK_LOAD_ERROR 5 T_CLK_MAP clk_load_error[]= { {-1,59,14+SCREEN_OFFLINE,306,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {1,59,310+SCREEN_OFFLINE,306,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {-1,LOAD_SLOT_S,SCREEN_OFFLINE,LOAD_SLOT_E,350,clk_load_proc,3,H_MS_DEFAULT}, {-1,30,0,85,14,clk_load_konec,2,H_MS_DEFAULT}, {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, }; static char clk_load_proc_menu(int id,int xa,int ya,int xr,int yr) { id=bright_slot(yr-18); xa;ya;xr;yr; if (ms_last_event.event_type & 0x2 && id>=0 && used_pos[id]) send_message(E_CLOSE_MAP,id); return 1; } #define CLK_LOAD_MENU 5 T_CLK_MAP clk_load_menu[]= { {-1,59,14+SCREEN_OFFLINE,306,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {1,59,310+SCREEN_OFFLINE,306,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {-1,LOAD_SLOT_S,SCREEN_OFFLINE,LOAD_SLOT_E,350,clk_load_proc_menu,3,H_MS_DEFAULT}, {-1,0,0,639,479,clk_load_konec,8,H_MS_DEFAULT}, {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, }; static char clk_load_proc(int id,int xa,int ya,int xr,int yr) { id=bright_slot(yr-18); xa;ya;xr;yr; if (ms_last_event.event_type & 0x2 && id>=0 && used_pos[id]) { if (load_game(id)) { message(1,0,0,"",texty[79],texty[80]); redraw_load(); showview(0,0,0,0); change_click_map(clk_load_error,CLK_LOAD_ERROR); } else { unwire_proc(); wire_proc(); if (battle) konec_kola(); unwire_proc(); if (!load_another) { wire_main_functs(); cur_mode=MD_GAME; bott_draw(1); pick_set_cursor(); for(id=0;idmsg==E_KEYBOARD) { c=va_arg(msg->data, int); if (c==13) { send_message(E_KEYBOARD,c); save_game(slot_pos,global_gamename); wire_proc(); read_slot_list(); msg->msg=-2; } else if(c==27) { send_message(E_KEYBOARD,c); msg->msg=-2; wire_save_load(1); } } } static char clk_askname_stop(int id,int xa,int ya,int xr,int yr) { id,xa,ya,xr,yr; if (ms_last_event.event_type & 0x2) { send_message(E_KEYBOARD,13); return 1; } else { send_message(E_KEYBOARD,27); return 1; } } static void save_it(char ok) { if (ok) { save_game(slot_pos,global_gamename); read_slot_list(); wire_proc(); GlobEvent(MAGLOB_AFTERSAVE,viewsector,viewdir); } else { wire_save_load(force_save); } } #define CLK_ASK_NAME 2 T_CLK_MAP clk_ask_name[]= { {-1,0,0,639,479,clk_askname_stop,8+2,H_MS_DEFAULT}, {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, }; void wire_ask_gamename(int id) { int x,y; x=SAVE_SLOT_S; y=id*SLOT_SPACE+21+SCREEN_OFFLINE; slot_pos=id; schovej_mysku(); put_picture(x,y,ablock(H_LOADTXTR)); strcpy(global_gamename,slot_list[id]); clk_ask_name[0].id=add_task(16384,type_text_v2,global_gamename,x,y,SAVE_SLOT_E-SAVE_SLOT_S,SAVE_NAME_SIZE,H_FBOLD,RGB555(31,31,0),save_it); change_click_map(clk_ask_name,CLK_ASK_NAME); ukaz_mysku(); } #define CLK_SAVELOAD 11 T_CLK_MAP clk_load[]= { {-1,LOAD_SLOT_S,SCREEN_OFFLINE,LOAD_SLOT_E,350,clk_load_proc,3,H_MS_DEFAULT}, {-1,59,14+SCREEN_OFFLINE,306,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {1,59,310+SCREEN_OFFLINE,306,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {-1,54,378,497,479,start_invetory,2+8,-1}, {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, {-1,291,0,313,14,go_book,2,H_MS_DEFAULT}, {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, {1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT}, {-1,267,0,289,15,clk_sleep,2,H_MS_DEFAULT}, {-1,0,0,639,479,close_saveload,9,H_MS_DEFAULT}, }; static char clk_save_proc(int id,int xa,int ya,int xr,int yr) { id=bright_slot(yr-18); xa;ya;xr;yr; if (ms_last_event.event_type & 0x2 && id>=0) { unwire_proc(); wire_ask_gamename(id); } return 1; } T_CLK_MAP clk_save[]= { {-1,SAVE_SLOT_S,SCREEN_OFFLINE,SAVE_SLOT_E,350,clk_save_proc,3,H_MS_DEFAULT}, {-1,59+274,14+SCREEN_OFFLINE,306+274,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {1,59+274,310+SCREEN_OFFLINE,306+274,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, {-1,54,378,497,479,start_invetory,2+8,-1}, {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, {-1,291,0,313,14,go_book,2,H_MS_DEFAULT}, {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, {0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT}, {-1,267,0,289,15,clk_sleep,2,H_MS_DEFAULT}, {-1,0,0,639,479,close_saveload,9,H_MS_DEFAULT}, }; static void saveload_keyboard(EVENT_MSG *msg,void **_) { if (msg->msg == E_KEYBOARD) { int v = quit_request_as_escape(va_arg(msg->data, int)); switch (v>>8) { case 1:unwire_proc();wire_proc();break; case 'H':if (last_select>0) bright_slot((last_select-1)*SLOT_SPACE+1);break; case 'P':if (last_selectSTATE_CUR_VER) goto err; if (!temp_storage_read(&i,sizeof(mapsize)*1,fsta)) goto err; if (mapsize!=i) goto err; SEND_LOG("(SAVELOAD) Partial restore for map: %s (%s)",level_fname,"START"); temp_storage_read(&siz,1*sizeof(siz),fsta); bf=(char *)getmem(siz); if (!temp_storage_read(bf,siz*1,fsta)) goto err; for (i=0;i>3]>>(i & 7)) & 1; load_map_description(fsta); while (temp_storage_read(&i,1*2,fsta) && i<=mapsize*4) if (temp_storage_read(map_sides+i,1*sizeof(TSTENA),fsta)!=sizeof(TSTENA)) goto err; while (temp_storage_read(&i,1*2,fsta) && i<=mapsize) if (temp_storage_read(map_sectors+i,1*sizeof(TSECTOR),fsta)!=sizeof(TSECTOR)) goto err; res=0; err: free(bf); temp_storage_close_rd(fsta); SEND_LOG("(SAVELOAD) Partial restore for map: %s (%s)",level_fname,"DONE"); return res; } int load_map_automap(char *mapfile) { int i; SEND_LOG("(SAVEGAME) CRITICAL SECTION - Swapping maps: %s <-> %s",level_fname,mapfile); kill_all_sounds(); for(i=0;i