void savegame(struct memfile *mf) { int count = 0; xchar ltmp; store_version(mf); /* Place flags, player info & moves at the beginning of the save. * This makes it possible to read them in nh_get_savegame_status without * parsing all the dungeon and level data */ save_flags(mf); save_you(mf, &u); mwrite32(mf, moves); save_mon(mf, &youmonst); /* store dungeon layout */ save_dungeon(mf); savelevchn(mf); /* store levels */ for (ltmp = 1; ltmp <= maxledgerno(); ltmp++) if (levels[ltmp]) count++; mwrite32(mf, count); for (ltmp = 1; ltmp <= maxledgerno(); ltmp++) { if (!levels[ltmp]) continue; mwrite8(mf, ltmp); /* level number*/ savelev(mf, ltmp); /* actual level*/ } savegamestate(mf); }
TDB_EXPORT tdb_error tdb_cons_finalize(tdb_cons *cons) { struct tdb_file items_mmapped; uint64_t num_events = cons->events.next; int ret = 0; memset(&items_mmapped, 0, sizeof(struct tdb_file)); /* finalize event items */ if ((ret = arena_flush(&cons->items))) goto done; if (cons->items.fd && fclose(cons->items.fd)) { cons->items.fd = NULL; ret = TDB_ERR_IO_CLOSE; goto done; } cons->items.fd = NULL; if (cons->tempfile[0]){ if (num_events && cons->num_ofields) { if (file_mmap(cons->tempfile, NULL, &items_mmapped, NULL)){ ret = TDB_ERR_IO_READ; goto done; } } TDB_TIMER_DEF TDB_TIMER_START if ((ret = store_lexicons(cons))) goto done; TDB_TIMER_END("encoder/store_lexicons") TDB_TIMER_START if ((ret = store_uuids(cons))) goto done; TDB_TIMER_END("encoder/store_uuids") TDB_TIMER_START if ((ret = store_version(cons))) goto done; TDB_TIMER_END("encoder/store_version") TDB_TIMER_START if ((ret = tdb_encode(cons, (const tdb_item*)items_mmapped.data))) goto done; TDB_TIMER_END("encoder/encode") } done: if (items_mmapped.ptr) munmap(items_mmapped.ptr, items_mmapped.mmap_size); if (cons->tempfile[0]) unlink(cons->tempfile); if (!ret){ #ifdef HAVE_ARCHIVE_H if (cons->output_format == TDB_OPT_CONS_OUTPUT_FORMAT_PACKAGE) ret = cons_package(cons); #endif } return ret; }