/* * Handle signal -- abort, kill, etc */ static void handle_signal_abort(int sig) { /* Disable handler */ (void)(*signal_aux)(sig, SIG_IGN); /* Nothing to save, just quit */ if (!character_generated || character_saved) quit(NULL); /* Clear the bottom line */ Term_erase(0, 23, 255); /* Give a warning */ Term_putstr(0, 23, -1, TERM_RED, "A gruesome software bug LEAPS out at you!"); /* Message */ Term_putstr(45, 23, -1, TERM_RED, "Panic save..."); /* Flush output */ Term_fresh(); /* Panic Save p_ptr->panic_save = 1; */ /* Panic save */ my_strcpy(p_ptr->died_from, "(panic save)", sizeof(p_ptr->died_from)); /* Forbid suspend */ signals_ignore_tstp(); /* Attempt to save */ if (old_save()) { Term_putstr(45, 23, -1, TERM_RED, "Panic save succeeded!"); } /* Save failed */ else { Term_putstr(45, 23, -1, TERM_RED, "Panic save failed!"); } /* Flush output */ Term_fresh(); /* Quit */ quit("software bug"); }
/** * Save the game */ void save_game(void) { char name[80]; char path[1024]; /* Disturb the player */ disturb(player, 1); /* Clear messages */ event_signal(EVENT_MESSAGE_FLUSH); /* Handle stuff */ handle_stuff(player); /* Message */ prt("Saving game...", 0, 0); /* Refresh */ Term_fresh(); /* The player is not dead */ my_strcpy(player->died_from, "(saved)", sizeof(player->died_from)); /* Forbid suspend */ signals_ignore_tstp(); /* Save the player */ if (savefile_save(savefile)) prt("Saving game... done.", 0, 0); else prt("Saving game... failed!", 0, 0); /* Refresh */ Term_fresh(); /* Save the window prefs */ strnfmt(name, sizeof(name), "%s.prf", player_safe_name(player, TRUE)); path_build(path, sizeof(path), ANGBAND_DIR_USER, name); if (!prefs_save(path, option_dump, "Dump window settings")) prt("Failed to save subwindow preferences", 0, 0); /* Allow suspend again */ signals_handle_tstp(); /* Refresh */ Term_fresh(); /* Note that the player is not dead */ my_strcpy(player->died_from, "(alive and well)", sizeof(player->died_from)); }
void cmsg_print(byte color, cptr msg) { if (world_monster) return; if (statistics_hack) return; /* Hack: msg_print(NULL) requests a flush if needed */ if (!msg) { if (!msg_line_is_empty()) msg_line_flush(); return; } if (character_generated) { if (_msg_append && _msg_count) cmsg_append(color, msg); else cmsg_add(color, msg); } msg_line_display(color, msg); if (auto_more_state == AUTO_MORE_SKIP_ONE) auto_more_state = AUTO_MORE_PROMPT; p_ptr->window |= PW_MESSAGE; window_stuff(); if (fresh_message) /* ?? */ Term_fresh(); _msg_append = TRUE; }
/* * Hack -- display object recall in sub-windows */ static void fix_object(void) { s32b j; /* Scan windows */ for (j = 0; j < 8; j++) { term *old = Term; /* No window */ if (!angband_term[j]) continue; /* No relevant flags */ if (!flag_exists(&window_flag[j], FLAG_PW_OBJECT)) continue; /* Activate */ Term_activate(angband_term[j]); /* Clear */ Term_clear(); /* Display object info */ if (tracked_object) if (!object_out_desc(tracked_object, NULL, FALSE, FALSE)) text_out("You see nothing special."); /* Fresh */ Term_fresh(); /* Restore */ Term_activate(old); } }
bool send_world_score(bool do_send) { #ifdef WORLD_SCORE if(send_score && do_send) { if(easy_band) { msg_print("Since you are in the Easy Mode, you cannot send score to world score server."); } else if(get_check_strict("Do you send score to the world score sever? ", (CHECK_NO_ESCAPE | CHECK_NO_HISTORY))) { errr err; prt("",0,0); prt("Sending...",0,0); Term_fresh(); screen_save(); err = report_score(); screen_load(); if (err) { return FALSE; } prt("Completed. Hit any key.", 0, 0); (void)inkey(); } else return FALSE; } #endif return TRUE; }
/* * Hack -- display monster recall in sub-windows */ static void fix_monster(void) { s32b j; /* Scan windows */ for (j = 0; j < 8; j++) { term *old = Term; /* No window */ if (!angband_term[j]) continue; /* No relevant flags */ if (!flag_exists(&window_flag[j], FLAG_PW_MONSTER)) continue; /* Activate */ Term_activate(angband_term[j]); /* Display monster race info */ if (monster_race_idx) display_roff(monster_race_idx, monster_ego_idx); /* Fresh */ Term_fresh(); /* Restore */ Term_activate(old); } }
/*! * @brief スコアサーバへの転送処理 * @param do_send 実際に転送ア処置を行うか否か * @return 転送が成功したらTRUEを返す */ bool send_world_score(bool do_send) { #ifdef WORLD_SCORE if(send_score && do_send) { if(easy_band) { msg_print(_("初心者モードではワールドスコアに登録できません。", "Since you are in the Easy Mode, you cannot send score to world score server.")); } else if(get_check_strict(_("スコアをスコア・サーバに登録しますか? ", "Do you send score to the world score sever? "), (CHECK_NO_ESCAPE | CHECK_NO_HISTORY))) { errr err; prt("",0,0); prt(_("送信中..", "Sending..."),0,0); Term_fresh(); screen_save(); err = report_score(); screen_load(); if (err) { return FALSE; } prt(_("完了。何かキーを押してください。", "Completed. Hit any key."), 0, 0); (void)inkey(); } else return FALSE; } #endif return TRUE; }
bool target_set_closest(int mode) { int y, x, m_idx; monster_type *m_ptr; char m_name[80]; bool visibility; struct point_set *targets; /* Cancel old target */ target_set_monster(0); /* Get ready to do targetting */ targets = target_set_interactive_prepare(mode); /* If nothing was prepared, then return */ if (point_set_size(targets) < 1) { msg("No Available Target."); point_set_dispose(targets); return FALSE; } /* Find the first monster in the queue */ y = targets->pts[0].y; x = targets->pts[0].x; m_idx = cave->m_idx[y][x]; /* Target the monster, if possible */ if ((m_idx <= 0) || !target_able(m_idx)) { msg("No Available Target."); point_set_dispose(targets); return FALSE; } /* Target the monster */ m_ptr = cave_monster(cave, m_idx); monster_desc(m_name, sizeof(m_name), m_ptr, 0x00); if (!(mode & TARGET_QUIET)) msg("%^s is targeted.", m_name); Term_fresh(); /* Set up target information */ monster_race_track(m_ptr->r_idx); health_track(p_ptr, cave->m_idx[y][x]); target_set_monster(m_idx); /* Visual cue */ Term_get_cursor(&visibility); (void)Term_set_cursor(TRUE); move_cursor_relative(y, x); Term_redraw_section(x, y, x, y); /* TODO: what's an appropriate amount of time to spend highlighting */ Term_xtra(TERM_XTRA_DELAY, 150); (void)Term_set_cursor(visibility); point_set_dispose(targets); return TRUE; }
/** * Redraw the screen * * This command performs various low level updates, clears all the "extra" * windows, does a total redraw of the main window, and requests all of the * interesting updates and redraws that I can think of. * * This command is also used to "instantiate" the results of the user * selecting various things, such as graphics mode, so it must call * the "TERM_XTRA_REACT" hook before redrawing the windows. * */ void do_cmd_redraw(void) { int j; term *old = Term; /* Low level flush */ Term_flush(); /* Reset "inkey()" */ event_signal(EVENT_INPUT_FLUSH); if (character_dungeon) verify_panel(); /* Hack -- React to changes */ Term_xtra(TERM_XTRA_REACT, 0); if (character_dungeon) { /* Combine the pack (later) */ player->upkeep->notice |= (PN_COMBINE); /* Update torch, gear */ player->upkeep->update |= (PU_TORCH | PU_INVEN); /* Update stuff */ player->upkeep->update |= (PU_BONUS | PU_HP | PU_SPELLS); /* Fully update the visuals */ player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Redraw everything */ player->upkeep->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_INVEN | PR_EQUIP | PR_MESSAGE | PR_MONSTER | PR_OBJECT | PR_MONLIST | PR_ITEMLIST); } /* Clear screen */ Term_clear(); if (character_dungeon) { /* Hack -- update */ handle_stuff(player); /* Place the cursor on the player */ if (0 != character_dungeon) move_cursor_relative(player->px, player->py); } /* Redraw every window */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { if (!angband_term[j]) continue; Term_activate(angband_term[j]); Term_redraw(); Term_fresh(); Term_activate(old); } }
/** * Flush the output before displaying for emphasis */ void bell_message(game_event_type unused, game_event_data *data, void *user) { /* Flush the output */ Term_fresh(); display_message(unused, data, user); player->upkeep->redraw |= PR_MESSAGE; }
/* * Save the game */ void save_game(void) { /* Disturb the player */ disturb(1, 0); /* Clear messages */ message_flush(); /* Handle stuff */ handle_stuff(); /* Message */ prt("Saving game...", 0, 0); /* Refresh */ Term_fresh(); /* The player is not dead */ my_strcpy(p_ptr->died_from, "(saved)", sizeof(p_ptr->died_from)); /* Forbid suspend */ signals_ignore_tstp(); /* Save the player */ if (old_save()) { prt("Saving game... done.", 0, 0); } /* Save failed (oops) */ else { prt("Saving game... failed!", 0, 0); } /* Allow suspend again */ signals_handle_tstp(); /* Refresh */ Term_fresh(); /* Note that the player is not dead */ my_strcpy(p_ptr->died_from, "(alive and well)", sizeof(p_ptr->died_from)); }
/* * Redraw (and refresh) the whole window. */ errr Term_redraw(void) { /* Force "total erase" */ Term->total_erase = TRUE; /* Hack -- Refresh */ Term_fresh(); /* Success */ return (0); }
/* * Hack -- Show information on the screen, one line at a time. * * Avoid the top two lines, to avoid interference with "msg_print()". */ static void note(cptr msg) { static int y = 2; /* Draw the message */ prt(msg, y, 0); /* Advance one line (wrap if needed) */ if (++y >= 24) y = 2; /* Flush it */ Term_fresh(); }
/** * Load the attr/char at each point along "path" which is on screen from * "a" and "c". This was saved in draw_path(). */ static void load_path(u16b path_n, u16b *path_g, wchar_t *c, int *a) { int i; for (i = 0; i < path_n; i++) { int y = GRID_Y(path_g[i]); int x = GRID_X(path_g[i]); if (!panel_contains(y, x)) continue; move_cursor_relative(y, x); Term_addch(a[i], c[i]); } Term_fresh(); }
/* * Load the attr/char at each point along "path" which is on screen from * "a" and "c". This was saved in draw_path(). */ static void load_path(u16b path_n, u16b *path_g, char *c, byte *a) { int i; for (i = 0; i < path_n; i++) { if (!panel_contains(GRID_Y(path_g[i]), GRID_X(path_g[i]))) continue; move_cursor_relative(GRID_Y(path_g[i]), GRID_X(path_g[i])); (void)Term_addch(a[i], c[i]); } (void)Term_fresh(); }
/* * Hack -- Show information on the screen, one line at a time. * * Avoid the top two lines, to avoid interference with "note()". */ void note(const char *message) { static int y = 2; /* Draw the message */ prt(message, y, 0); pause_line(Term); /* Advance one line (wrap if needed) */ if (++y >= 24) y = 2; /* Flush it */ Term_fresh(); }
/* * Handle signals -- suspend * * Actually suspend the game, and then resume cleanly */ static void handle_signal_suspend(int sig) { /* Protect errno from library calls in signal handler */ int save_errno = errno; /* Disable handler */ (void)(*signal_aux)(sig, SIG_IGN); #ifdef SIGSTOP /* Flush output */ Term_fresh(); /* Suspend the "Term" */ Term_xtra(TERM_XTRA_ALIVE, 0); /* Suspend ourself */ (void)kill(0, SIGSTOP); /* Resume the "Term" */ Term_xtra(TERM_XTRA_ALIVE, 1); /* Redraw the term */ Term_redraw(); /* Flush the term */ Term_fresh(); #endif /* Restore handler */ (void)(*signal_aux)(sig, handle_signal_suspend); /* Restore errno */ errno = save_errno; }
/* * Display a "small-scale" map of the dungeon. * * Note that the "player" is always displayed on the map. */ void do_cmd_view_map(void) { int cy, cx; byte w, h; const char *prompt = "Hit any key to continue"; if (Term->view_map_hook) { (*(Term->view_map_hook))(Term); return; } /* Save screen */ screen_save(); /* Note */ prt("Please wait...", 0, 0); /* Flush */ Term_fresh(); /* Clear the screen */ Term_clear(); /* store the tile multipliers */ w = tile_width; h = tile_height; tile_width = 1; tile_height = 1; /* Display the map */ display_map(&cy, &cx); /* Show the prompt */ put_str(prompt, Term->hgt - 1, Term->wid / 2 - strlen(prompt) / 2); /* Highlight the player */ Term_gotoxy(cx, cy); /* Get any key */ (void)anykey(); /* Restore the tile multipliers */ tile_width = w; tile_height = h; /* Load screen */ screen_load(); }
/* * Flush the screen, make a noise */ void bell(const char *reason) { /* Mega-Hack -- Flush the output */ Term_fresh(); /* Hack -- memorize the reason if possible */ if (character_generated && reason) { message_add(reason, MSG_BELL); /* Window stuff */ p_ptr->redraw |= (PR_MESSAGE); redraw_stuff(p_ptr); } /* Flush the input (later!) */ flush(); }
/* * Hack -- display recent messages in sub-windows * * XXX XXX XXX Adjust for width and split messages */ void fix_message(void) { s32b j, i; s32b w, h; s32b x, y; /* Scan windows */ for (j = 0; j < 8; j++) { term *old = Term; /* No window */ if (!angband_term[j]) continue; /* No relevant flags */ if (!flag_exists(&window_flag[j], FLAG_PW_MESSAGE)) continue; /* Activate */ Term_activate(angband_term[j]); /* Get size */ Term_get_size(&w, &h); /* Dump messages */ for (i = 0; i < h; i++) { /* Dump the message on the appropriate line */ display_message(0, (h - 1) - i, strlen(message_str((s16b)i)), message_color((s16b)i), message_str((s16b)i)); /* Cursor */ Term_locate(&x, &y); /* Clear to end of line */ Term_erase(x, y, 255); } /* Fresh */ Term_fresh(); /* Restore */ Term_activate(old); } }
/** * Redraw a term when it is resized */ void redraw_window(void) { /* Only if the dungeon exists */ if (!character_dungeon) return; /* Hack - Activate term zero for the redraw */ Term_activate(&term_screen[0]); /* Hack -- react to changes */ Term_xtra(TERM_XTRA_REACT, 0); /* Hack -- update */ handle_stuff(p_ptr); /* Redraw */ Term_redraw(); /* Refresh */ Term_fresh(); }
/** * Target closest monster. * * XXX: Move to using CMD_TARGET_CLOSEST at some point instead of invoking * target_set_closest() directly. */ void textui_target_closest(void) { if (target_set_closest(TARGET_KILL)) { bool visibility; int x, y; target_get(&x, &y); /* Visual cue */ Term_fresh(); Term_get_cursor(&visibility); (void)Term_set_cursor(TRUE); move_cursor_relative(y, x); Term_redraw_section(x, y, x, y); /* TODO: what's an appropriate amount of time to spend highlighting */ Term_xtra(TERM_XTRA_DELAY, 150); (void)Term_set_cursor(visibility); } }
void pre_turn_refresh(void) { term *old = Term; int j; if (character_dungeon) { /* Redraw map */ player->upkeep->redraw |= (PR_MAP | PR_STATE); player->upkeep->redraw |= (PR_MONLIST | PR_ITEMLIST); handle_stuff(player); move_cursor_relative(player->px, player->py); for (j = 0; j < ANGBAND_TERM_MAX; j++) { if (!angband_term[j]) continue; Term_activate(angband_term[j]); Term_fresh(); } } Term_activate(old); }
/* * Show scores. */ void show_scores(void) { screen_save(); /* Display the scores */ if (character_generated) { predict_score(); } else { high_score scores[MAX_HISCORES]; highscore_read(scores, N_ELEMENTS(scores)); display_scores_aux(scores, 0, MAX_HISCORES, -1); } screen_load(); /* Hack - Flush it */ Term_fresh(); }
/* * Redraw part of a window. */ errr Term_redraw_section(int x1, int y1, int x2, int y2) { int i, j; char *c_ptr; /* Bounds checking */ if (y2 >= Term->hgt) y2 = Term->hgt - 1; if (x2 >= Term->wid) x2 = Term->wid - 1; if (y1 < 0) y1 = 0; if (x1 < 0) x1 = 0; /* Set y limits */ Term->y1 = y1; Term->y2 = y2; /* Set the x limits */ for (i = Term->y1; i <= Term->y2; i++) { Term->x1[i] = x1; Term->x2[i] = x2; c_ptr = Term->old->c[i]; /* Clear the section so it is redrawn */ for (j = x1; j <= x2; j++) { /* Hack - set the old character to "none" */ c_ptr[j] = 0; } } /* Hack -- Refresh */ Term_fresh(); /* Success */ return (0); }
/* * Rest (restores hit points and mana and such) */ void do_cmd_rest(cmd_code code, cmd_arg args[]) { /* * A little sanity checking on the input - only the specified negative * values are valid. */ if ((args[0].choice < 0) && ((args[0].choice != REST_COMPLETE) && (args[0].choice != REST_ALL_POINTS) && (args[0].choice != REST_SOME_POINTS))) { return; } /* Save the rest code */ p_ptr->resting = args[0].choice; /* Truncate overlarge values */ if (p_ptr->resting > 9999) p_ptr->resting = 9999; /* Take a turn XXX XXX XXX (?) */ p_ptr->energy_use = 100; /* Cancel searching */ p_ptr->searching = FALSE; /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Handle stuff */ handle_stuff(); /* Refresh XXX XXX XXX */ Term_fresh(); }
/* * Flush the screen, make a noise */ void bell(cptr reason) { /* Mega-Hack -- Flush the output */ Term_fresh(); /* Hack -- memorize the reason if possible */ if (character_generated && reason) { message_add(reason, MSG_BELL); /* Window stuff */ p_ptr->window |= (PW_MESSAGE); /* Force window redraw */ window_stuff(); } /* Make a bell noise (if allowed) */ if (ring_bell) Term_xtra(TERM_XTRA_NOISE, 0); /* Flush the input (later!) */ flush(); }
void browse_movie(void) { Term_clear(); Term_fresh(); Term_xtra(TERM_XTRA_REACT, 0); while (read_movie_file() == 0) { while (fresh_queue.next != fresh_queue.tail) { if (!flush_ringbuf_client()) { Term_xtra(TERM_XTRA_FLUSH, 0); /* ソケットにデータが来ているかどうか調べる */ #ifdef WINDOWS Sleep(WAIT); #else usleep(WAIT); #endif } } } }
/* * Output a rarity graph for a type of object. * * Use a monte-carlo method to calculate the probabilities. */ static void prt_alloc(const object_type *o_ptr, int row, int col, u32b monte) { u32b i, j; u32b maxd = 1, maxr = 1, maxt = 1; u32b rarity[MAX_DEPTH]; u32b total[MAX_DEPTH]; u32b display[20]; byte c = TERM_WHITE; cptr r = "+--common--+"; u16b kind = o_ptr->k_idx; u16b home = k_info[kind].level; /* Wipe the tables */ (void)C_WIPE(rarity, MAX_DEPTH, u32b); (void)C_WIPE(total, MAX_DEPTH, u32b); (void)C_WIPE(display, 20, u32b); msg_print(NULL); prt("Calculating probability distribution - please wait.", 0, 0); /* Refresh */ Term_fresh(); /* Scan all entries */ for (i = 0; i < MAX_DEPTH; i++) { for (j = 0; j < monte; j++) { if (get_obj_num(i, 0) == kind) rarity[i]++; } total[i] = monte; } /* Find maxima */ for (i = 0; i < MAX_DEPTH; i++) { if (rarity[i] > maxr) maxr = rarity[i]; if (total[i] > maxt) maxt = total[i]; } /* Simulate a log graph */ if (maxt / maxr > 32) { c = TERM_L_WHITE; r = "+-uncommon-+"; } if (maxt / maxr > 1024) { c = TERM_SLATE; r = "+---rare---+"; } if (maxt / maxr > 32768L) { c = TERM_L_DARK; r = "+--unique--+"; } /* Calculate probabilities for each range */ for (i = 0; i < 20; i++) { /* Shift the values into view */ for (j = i * MAX_DEPTH / 20; j < (i + 1) * MAX_DEPTH / 20; j++) { display[i] += rarity[j] * maxt * 10 / total[j]; } /* Correct proportions */ display[i] /= maxr; /* Track maximum */ if (display[i] > maxd) maxd = display[i]; } /* Normalize */ for (i = 0; i < 20; i++) { display[i] = display[i] * 10 / maxd; } /* Graph the rarities */ for (i = 0; i < 20; i++) { Term_putch(col, row + i + 1, TERM_WHITE, '|'); /* Note the level */ if ((i * MAX_DEPTH / 20 <= home) && (home < (i + 1) * MAX_DEPTH / 20)) { c_prt(TERM_RED, format("%.*s", display[i], "**********"), row + i + 1, col + 1); } else { c_prt(c, format("%.*s", display[i], "**********"), row + i + 1, col + 1); } } /* Make it look nice */ prt(r, row, col); Term_putch(col, row + 2, TERM_WHITE, '6'); Term_putch(col, row + 8, TERM_WHITE, 'A'); Term_putch(col, row + 9, TERM_WHITE, 'L'); Term_putch(col, row + 10, TERM_WHITE, 'L'); Term_putch(col, row + 11, TERM_WHITE, 'O'); Term_putch(col, row + 12, TERM_WHITE, 'C'); prt("+", row + 21, col); }
/* * Get a keypress from the user. * * This function recognizes a few "global parameters". These are variables * which, if set to TRUE before calling this function, will have an effect * on this function, and which are always reset to FALSE by this function * before this function returns. Thus they function just like normal * parameters, except that most calls to this function can ignore them. * * If "inkey_xtra" is TRUE, then all pending keypresses will be flushed. * This is set by flush(), which doesn't actually flush anything itself * but uses that flag to trigger delayed flushing. * * If "inkey_scan" is TRUE, then we will immediately return "zero" if no * keypress is available, instead of waiting for a keypress. * * If "inkey_flag" is TRUE, then we are waiting for a command in the main * map interface, and we shouldn't show a cursor. * * If we are waiting for a keypress, and no keypress is ready, then we will * refresh (once) the window which was active when this function was called. * * Note that "back-quote" is automatically converted into "escape" for * convenience on machines with no "escape" key. * * If "angband_term[0]" is not active, we will make it active during this * function, so that the various "main-xxx.c" files can assume that input * is only requested (via "Term_inkey()") when "angband_term[0]" is active. * * Mega-Hack -- This function is used as the entry point for clearing the * "signal_count" variable, and of the "character_saved" variable. * * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal * control of the keyboard from the user. */ ui_event inkey_ex(void) { bool cursor_state; ui_event kk; ui_event ke = EVENT_EMPTY; bool done = FALSE; term *old = Term; /* Delayed flush */ if (inkey_xtra) { Term_flush(); inkey_next = NULL; inkey_xtra = FALSE; } /* Hack -- Use the "inkey_next" pointer */ if (inkey_next && inkey_next->code) { /* Get next character, and advance */ ke.key = *inkey_next++; /* Cancel the various "global parameters" */ inkey_flag = FALSE; inkey_scan = 0; /* Accept result */ return (ke); } /* Forget pointer */ inkey_next = NULL; #ifdef ALLOW_BORG /* Mega-Hack -- Use the special hook */ if (inkey_hack) { ke.key = (*inkey_hack)(inkey_xtra); if (ke.key.type != EVT_NONE) { /* Cancel the various "global parameters" */ inkey_flag = FALSE; inkey_scan = 0; ke.type = EVT_KBRD; /* Accept result */ return (ke); } } #endif /* ALLOW_BORG */ /* Get the cursor state */ (void)Term_get_cursor(&cursor_state); /* Show the cursor if waiting, except sometimes in "command" mode */ if (!inkey_scan && (!inkey_flag || character_icky)) (void)Term_set_cursor(TRUE); /* Hack -- Activate main screen */ Term_activate(term_screen); /* Get a key */ while (ke.type == EVT_NONE) { /* Hack -- Handle "inkey_scan == SCAN_INSTANT */ if (inkey_scan == SCAN_INSTANT && (0 != Term_inkey(&kk, FALSE, FALSE))) break; /* Hack -- Flush output once when no key ready */ if (!done && (0 != Term_inkey(&kk, FALSE, FALSE))) { /* Hack -- activate proper term */ Term_activate(old); /* Flush output */ Term_fresh(); /* Hack -- activate main screen */ Term_activate(term_screen); /* Mega-Hack -- reset saved flag */ character_saved = FALSE; /* Mega-Hack -- reset signal counter */ signal_count = 0; /* Only once */ done = TRUE; } /* Get a key (see above) */ ke = inkey_aux(inkey_scan); /* Handle mouse buttons */ if ((ke.type == EVT_MOUSE) && (OPT(mouse_buttons))) { /* Check to see if we've hit a button */ /* Assuming text buttons here for now - this would have to * change for GUI buttons */ char key = button_get_key(ke.mouse.x, ke.mouse.y); if (key) { /* Rewrite the event */ /* XXXmacro button implementation needs updating */ ke.type = EVT_BUTTON; ke.key.code = key; ke.key.mods = 0; /* Done */ break; } } /* Treat back-quote as escape */ if (ke.key.code == '`') ke.key.code = ESCAPE; } /* Hack -- restore the term */ Term_activate(old); /* Restore the cursor */ Term_set_cursor(cursor_state); /* Cancel the various "global parameters" */ inkey_flag = FALSE; inkey_scan = 0; /* Return the keypress */ return (ke); }