void replay(void) { char buf[BUFSZ]; fnchar logdir[BUFSZ], savedir[BUFSZ], filename[1024], *dir, **files; struct nh_menuitem *items; int i, n, fd, icount, size, filecount, pick[1]; enum nh_log_status status; struct nh_game_info gi; if (!get_gamedir(LOG_DIR, logdir)) logdir[0] = '\0'; if (!get_gamedir(SAVE_DIR, savedir)) savedir[0] = '\0'; if (*logdir) dir = logdir; else if (*savedir) dir = savedir; else { curses_msgwin("There are no games to replay."); return; } while (1) { filename[0] = '\0'; files = list_gamefiles(dir, &filecount); /* make sure there are some files to show */ if (!filecount) { if (dir == savedir) { curses_msgwin("There are no saved games to replay."); savedir[0] = '\0'; } else { curses_msgwin("There are no completed games to replay."); logdir[0] = '\0'; } dir = (dir == savedir) ? logdir : savedir; if (!*dir) return; continue; } icount = 0; size = filecount + 2; items = malloc(size * sizeof (struct nh_menuitem)); /* add all the files to the menu */ for (i = 0; i < filecount; i++) { fd = sys_open(files[i], O_RDWR, 0660); status = nh_get_savegame_status(fd, &gi); close(fd); describe_game(buf, status, &gi); add_menu_item(items, size, icount, (status == LS_IN_PROGRESS) ? 0 : icount + 1, buf, 0, FALSE); } if (dir == logdir && *savedir) { add_menu_txt(items, size, icount, "", MI_NORMAL); add_menu_item(items, size, icount, -1, "View saved games instead", '!', FALSE); } else if (dir == savedir && *logdir) { add_menu_txt(items, size, icount, "", MI_NORMAL); add_menu_item(items, size, icount, -1, "View saved games instead", '!', FALSE); } n = curses_display_menu(items, icount, "Pick a game to view", PICK_ONE, PLHINT_ANYWHERE, pick); free(items); filename[0] = '\0'; if (n > 0 && pick[0] != -1) fnncat(filename, files[pick[0] - 1], sizeof (filename) / sizeof (fnchar) - 1); for (i = 0; i < filecount; i++) free(files[i]); free(files); if (n <= 0) return; if (pick[0] == -1) { dir = (dir == savedir) ? logdir : savedir; continue; } /* we have a valid filename */ break; } fd = sys_open(filename, O_RDWR, 0660); replay_commandloop(fd); close(fd); }
nh_bool loadgame(void) { char buf[BUFSZ]; fnchar savedir[BUFSZ], filename[1024], **files; struct nh_menuitem *items; int size, icount, fd, i, n, ret, pick[1]; enum nh_log_status status; struct nh_game_info gi; if (!get_gamedir(SAVE_DIR, savedir)) { curses_raw_print("Could not find or create the save directory."); return FALSE; } files = list_gamefiles(savedir, &size); if (!size) { curses_msgwin("No saved games found."); return FALSE; } icount = 0; items = malloc(size * sizeof(struct nh_menuitem)); for (i = 0; i < size; i++) { fd = sys_open(files[i], O_RDWR, FILE_OPEN_MASK); status = nh_get_savegame_status(fd, &gi); close(fd); describe_game(buf, status, &gi); add_menu_item(items, size, icount, (status == LS_IN_PROGRESS) ? 0 : icount + 1, buf, 0, FALSE); } n = curses_display_menu(items, icount, "saved games", PICK_ONE, pick); free(items); filename[0] = '\0'; if (n > 0) fnncat(filename, files[pick[0]-1], sizeof(filename)/sizeof(fnchar)-1); for (i = 0; i < icount; i++) free(files[i]); free(files); if (n <= 0) return FALSE; fd = sys_open(filename, O_RDWR, FILE_OPEN_MASK); create_game_windows(); if (nh_restore_game(fd, NULL, FALSE) != GAME_RESTORED) { destroy_game_windows(); close(fd); if (curses_yn_function("Failed to load the save. Do you wish to delete the file?", "yn", 'n') == 'y') unlink(filename); return FALSE; } load_keymap(); /* need to load the keymap after the game has been started */ ret = commandloop(); free_keymap(); close(fd); destroy_game_windows(); cleanup_messages(); game_ended(ret, filename); return TRUE; }