void rungame(void) { int ret, role = initrole, race = initrace, gend = initgend, align = initalign; int fd = -1; char plname[BUFSZ]; fnchar filename[1024]; fnchar savedir[BUFSZ]; long t; if (!get_gamedir(SAVE_DIR, savedir)) { curses_raw_print("Could not find where to put the logfile for a new game."); return; } if (!player_selection(&role, &race, &gend, &align, random_player)) return; strncpy(plname, settings.plname, PL_NSIZ); /* The player name is set to "wizard" (again) in nh_start_game, so setting * it here just prevents wizmode player from being asked for a name. */ if (ui_flags.playmode == MODE_WIZARD) strcpy(plname, "wizard"); while (!plname[0]) curses_getline("what is your name?", plname); if (plname[0] == '\033') /* canceled */ return; t = (long)time(NULL); #if defined(WIN32) snwprintf(filename, 1024, L"%ls%ld_%hs.nhgame", savedir, t, plname); #else snprintf(filename, 1024, "%s%ld_%s.nhgame", savedir, t, plname); #endif fd = sys_open(filename, O_TRUNC | O_CREAT | O_RDWR, FILE_OPEN_MASK); if (fd == -1) { curses_raw_print("Could not create the logfile."); return; } create_game_windows(); if (!nh_start_game(fd, plname, role, race, gend, align, ui_flags.playmode)) { destroy_game_windows(); close(fd); return; } 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); }
void replay_commandloop(int fd) { int key, move, count; char buf[BUFSZ], qbuf[BUFSZ]; nh_bool ret, firsttime = TRUE; struct nh_replay_info rinfo; struct nh_cmd_arg noarg; struct nh_cmd_desc *cmd; create_game_windows(); if (!nh_view_replay_start(fd, &curses_replay_windowprocs, &rinfo)) return; load_keymap(); while (1) { draw_msgwin(); curses_update_status(NULL); draw_sidebar(); draw_replay_info(&rinfo); if (firsttime) show_replay_help(); firsttime = FALSE; key = get_map_key(TRUE); switch (key) { /* step forward */ case KEY_RIGHT: case ' ': ret = nh_view_replay_step(&rinfo, REPLAY_FORWARD, 1); draw_replay_info(&rinfo); if (ret == FALSE) { key = curses_msgwin("You have reached the end of this game. " "Go back or press ESC to exit."); if (key == KEY_ESC) goto out; } break; /* step backward */ case KEY_LEFT: nh_view_replay_step(&rinfo, REPLAY_BACKWARD, 1); draw_replay_info(&rinfo); break; case KEY_ESC: goto out; case 'g': strncpy(qbuf, "What move do you want to jump to?", BUFSZ); if (rinfo.max_moves > 0) sprintf(qbuf + strlen(qbuf), " (Max: %d)", rinfo.max_moves); curses_getline(qbuf, buf); if (buf[0] == '\033' || !(move = atoi(buf))) break; nh_view_replay_step(&rinfo, REPLAY_GOTO, move); break; case KEY_F(12): /* timetest! */ if (allow_timetest()) timetest(fd, &rinfo); break; default: count = 0; noarg.argtype = CMD_ARG_NONE; cmd = keymap[key]; if (!cmd) break; if (cmd->flags & CMD_UI) handle_internal_cmd(&cmd, &noarg, &count); if (cmd) nh_command(cmd->name, count, &noarg); break; } } out: nh_view_replay_finish(); free_keymap(); destroy_game_windows(); cleanup_messages(); }
static void mainmenu(void) { int menuresult[1]; int n = 1, logoheight, i; const char *const *copybanner = nh_get_copyright_banner(); const char **nhlogo; char verstr[32]; nh_bool first = TRUE; snprintf(verstr, ARRAY_SIZE(verstr), "Version %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL); #if defined(NETCLIENT) if (ui_flags.connection_only) { netgame(); return; } #endif load_keymap(); /* netgame() assumes the keymap isn't loaded */ while (n >= 0) { if (COLS >= 100) { nhlogo = nhlogo_large; logoheight = sizeof (nhlogo_large) / sizeof (nhlogo_large[0]); } else { nhlogo = nhlogo_small; logoheight = sizeof (nhlogo_small) / sizeof (nhlogo_small[0]); } wclear(basewin); wattron(basewin, A_BOLD | COLOR_PAIR(4)); for (i = 0; i < logoheight; i++) { wmove(basewin, i, (COLS - strlen(nhlogo[0])) / 2); if (nhlogo[i]) waddstr(basewin, nhlogo[i]); } wattroff(basewin, A_BOLD | COLOR_PAIR(4)); mvwaddstr(basewin, LINES - 3, 0, copybanner[0]); mvwaddstr(basewin, LINES - 2, 0, copybanner[1]); mvwaddstr(basewin, LINES - 1, 0, copybanner[2]); mvwaddstr(basewin, LINES - 4, COLS - strlen(verstr), verstr); wnoutrefresh(basewin); if (first) { network_motd(); first = FALSE; } menuresult[0] = EXITGAME; /* default action */ if (!override_hackdir) curses_display_menu_core( STATIC_MENULIST(mainmenu_items), NULL, PICK_ONE, menuresult, curses_menu_callback, 0, logoheight - 1, COLS, LINES - 3, FALSE, NULL, FALSE); else curses_display_menu_core( STATIC_MENULIST(mainmenu_items_noclient), NULL, PICK_ONE, menuresult, curses_menu_callback, 0, logoheight - 1, COLS, LINES - 3, FALSE, NULL, FALSE); if (*menuresult == CURSES_MENU_CANCELLED && !ui_flags.done_hup) continue; switch (menuresult[0]) { case NEWGAME: rungame(FALSE); break; case LOAD: loadgame(); break; case REPLAY: replay(); break; case OPTIONS: display_options(TRUE); break; #if defined(NETCLIENT) case NETWORK: free_keymap(); /* don't use the local keymap for server play */ netgame(); load_keymap(); break; #endif case TOPTEN: show_topten(NULL, -1, FALSE, FALSE); break; case EXITGAME: case CURSES_MENU_CANCELLED: /* in case of hangup */ n = -1; /* simulate menu cancel */ break; } } free_keymap(); }
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; }