*/
void do_cmd_save_game(player_type *creature_ptr, int is_autosave)
{
- if (is_autosave)
- msg_print(_("自動セーブ中", "Autosaving the game..."));
- else
- disturb(creature_ptr, TRUE, TRUE);
+ if (is_autosave)
+ msg_print(_("自動セーブ中", "Autosaving the game..."));
+ else
+ disturb(creature_ptr, TRUE, TRUE);
- msg_print(NULL);
- handle_stuff(creature_ptr);
- prt(_("ゲームをセーブしています...", "Saving game..."), 0, 0);
- term_fresh();
- (void)strcpy(creature_ptr->died_from, _("(セーブ)", "(saved)"));
- signals_ignore_tstp();
- if (save_player(creature_ptr))
- prt(_("ゲームをセーブしています... 終了", "Saving game... done."), 0, 0);
- else
- prt(_("ゲームをセーブしています... 失敗!", "Saving game... failed!"), 0, 0);
+ msg_print(NULL);
+ handle_stuff(creature_ptr);
+ prt(_("ゲームをセーブしています...", "Saving game..."), 0, 0);
+ term_fresh();
+ (void)strcpy(creature_ptr->died_from, _("(セーブ)", "(saved)"));
+ signals_ignore_tstp();
+ if (save_player(creature_ptr, SAVE_TYPE_NORMAL))
+ prt(_("ゲームをセーブしています... 終了", "Saving game... done."), 0, 0);
+ else
+ prt(_("ゲームをセーブしています... 失敗!", "Saving game... failed!"), 0, 0);
- signals_handle_tstp();
- term_fresh();
- (void)strcpy(creature_ptr->died_from, _("(元気に生きている)", "(alive and well)"));
- current_world_ptr->is_loading_now = FALSE;
- update_creature(creature_ptr);
- mproc_init(creature_ptr->current_floor_ptr);
- current_world_ptr->is_loading_now = TRUE;
+ signals_handle_tstp();
+ term_fresh();
+ (void)strcpy(creature_ptr->died_from, _("(元気に生きている)", "(alive and well)"));
+ current_world_ptr->is_loading_now = FALSE;
+ update_creature(creature_ptr);
+ mproc_init(creature_ptr->current_floor_ptr);
+ current_world_ptr->is_loading_now = TRUE;
}
-
/*!
* @brief セーブ後にゲーム中断フラグを立てる/
* Save the game and exit
*/
void do_cmd_save_and_exit(player_type *creature_ptr)
{
- creature_ptr->playing = FALSE;
- creature_ptr->leaving = TRUE;
- exe_write_diary(creature_ptr, DIARY_GAMESTART, 0, _("----ゲーム中断----", "--- Saved and Exited Game ---"));
-}
+ creature_ptr->playing = FALSE;
+ creature_ptr->leaving = TRUE;
+ exe_write_diary(creature_ptr, DIARY_GAMESTART, 0, _("----ゲーム中断----", "--- Saved and Exited Game ---"));
+}
\ No newline at end of file
player_ptr->wait_report_score = TRUE;
player_ptr->is_dead = FALSE;
- if (!save_player(player_ptr))
+ if (!save_player(player_ptr, SAVE_TYPE_NORMAL))
msg_print(_("セーブ失敗!", "death save failed!"));
}
-
/*!
* @brief ゲームクローズ時、プレイヤーが死亡しているかのチェックを行い死亡していないならば、確認キー入力とスコア表示、現フロアの初期化を行う。
* @param player_ptr プレイヤー構造体参照ポインタ。
kingly(player_ptr);
if (!cheat_save || get_check(_("死んだデータをセーブしますか? ", "Save death? "))) {
- if (!save_player(player_ptr))
+ if (!save_player(player_ptr, SAVE_TYPE_NORMAL))
msg_print(_("セーブ失敗!", "death save failed!"));
} else
do_send = FALSE;
}
clear_floor(player_ptr);
-}
+}
\ No newline at end of file
#include "grid/feature.h"
#include "grid/grid.h"
#include "info-reader/fixed-map-parser.h"
-#include "io/record-play-movie.h"
#include "io/inet.h"
#include "io/input-key-acceptor.h"
#include "io/input-key-processor.h"
#include "io/read-pref-file.h"
+#include "io/record-play-movie.h"
#include "io/screen-util.h"
#include "io/signal-handlers.h"
#include "io/write-diary.h"
} else {
player_ptr->wait_report_score = FALSE;
top_twenty(player_ptr);
- if (!save_player(player_ptr))
+ if (!save_player(player_ptr, SAVE_TYPE_NORMAL))
msg_print(_("セーブ失敗!", "death save failed!"));
}
return;
}
-
+
if (player_ptr->is_dead)
quit("Already dead.");
}
if ((current_world_ptr->wizard || cheat_live) && !get_check(_("死にますか? ", "Die? ")))
cheat_death(player_ptr);
- return;
+ return;
}
floor_ptr->inside_arena = FALSE;
init_world_floor_info(player_ptr);
else
restore_world_floor_info(player_ptr);
-
+
generate_world(player_ptr, new_game);
player_ptr->playing = TRUE;
reset_visuals(player_ptr, process_autopick_file_command);
process_game_turn(player_ptr);
close_game(player_ptr);
quit(NULL);
-}
+}
\ No newline at end of file
bool bound_walls_perm; /* Boundary walls become 'permanent wall' */
bool last_words; /* Leave last words when your character dies */
bool auto_dump; /* Dump a character record automatically */
+bool auto_debug_save; /* Dump a debug savedata every key input */
#ifdef WORLD_SCORE
bool send_score; /* Send score dump to the world score server */
#endif
extern bool bound_walls_perm; /* Boundary walls become 'permanent wall' */
extern bool last_words; /* Leave last words when your character dies */
extern bool auto_dump; /* Dump a character record automatically */
+extern bool auto_debug_save; /* Dump a debug savedata every key input */
#ifdef WORLD_SCORE
extern bool send_score; /* Send score dump to the world score server */
#endif
{ &send_score, TRUE, OPT_PAGE_GAMEPLAY, 4, 6, "send_score", _("スコアサーバにスコアを送る", "Send score dump to the world score server") },
#endif
+ { &auto_debug_save, TRUE, OPT_PAGE_GAMEPLAY, 4, 7, "auto_debug_save", _("デバッグ用セーブデータを自動生成する", "Create a debug save automatically") },
+
{ &allow_debug_opts, FALSE, OPT_PAGE_GAMEPLAY, 6, 11, "allow_debug_opts", _("デバッグ/詐欺オプションを許可する", "Allow use of debug/cheat options") },
/*** Disturbance ***/
concptr o_desc;
} option_type;
-#define MAX_OPTION_INFO 120
+#define MAX_OPTION_INFO 121
#define MAX_CHEAT_OPTIONS 10
#define MAX_AUTOSAVE_INFO 2
creature_ptr->panic_save = 1;
signals_ignore_tstp();
(void)strcpy(creature_ptr->died_from, _("(緊急セーブ)", "(panic save)"));
- if (!save_player(creature_ptr)) quit(_("緊急セーブ失敗!", "panic save failed!"));
+ if (!save_player(creature_ptr, SAVE_TYPE_NORMAL)) quit(_("緊急セーブ失敗!", "panic save failed!"));
quit(_("緊急セーブ成功!", "panic save succeeded!"));
}
concptr ANGBAND_DIR_INFO; //!< Help files (spoilers) for the online help (ascii) These files are portable between platforms
concptr ANGBAND_DIR_PREF; //!< Default user "preference" files (ascii) These files are rarely portable between platforms
concptr ANGBAND_DIR_SAVE; //!< Savefiles for current characters (binary)
+concptr ANGBAND_DIR_DEBUG_SAVE; //*< Savefiles for debug data
concptr ANGBAND_DIR_USER; //!< User "preference" files (ascii) These files are rarely portable between platforms
concptr ANGBAND_DIR_XTRA; //!< Various extra files (binary) These files are rarely portable between platforms
*/
char savefile[1024];
char savefile_base[40];
+char debug_savefile[1024];
/*!
* @brief プレイヤーステータスをファイルダンプ出力する
extern char savefile[1024];
extern char savefile_base[40];
+extern char debug_savefile[1024];
extern concptr ANGBAND_DIR;
extern concptr ANGBAND_DIR_APEX;
extern concptr ANGBAND_DIR_INFO;
extern concptr ANGBAND_DIR_PREF;
extern concptr ANGBAND_DIR_SAVE;
+extern concptr ANGBAND_DIR_DEBUG_SAVE;
extern concptr ANGBAND_DIR_USER;
extern concptr ANGBAND_DIR_XTRA;
#include "cmd-io/cmd-menu-content-table.h"
#include "cmd-io/macro-util.h"
#include "core/asking-player.h" // todo 相互依存している、後で何とかする.
+#include "game-option/game-play-options.h"
#include "game-option/input-options.h"
#include "inventory/inventory-slot-types.h"
#include "io/cursor.h"
#include "io/input-key-acceptor.h"
#include "main/sound-of-music.h"
+#include "save/save.h"
#include "system/floor-type-definition.h" // todo 違和感、後で調査する.
#include "system/object-type-definition.h"
#include "term/screen-processor.h" // todo 相互依存している、後で何とかする.
#include "util/string-processor.h"
#include "view/display-messages.h"
#include "window/main-window-util.h"
+#include "world/world.h"
/*
* Keymaps for each "mode" associated with each keypress.
use_menu = FALSE;
while (TRUE) {
+ if (!macro_running() && !command_new && auto_debug_save)
+ save_player(player_ptr, SAVE_TYPE_DEBUG);
+
if (command_new) {
msg_erase();
cmd = command_new;
signals_ignore_tstp();
- if (save_player(p_ptr)) {
+ if (save_player(p_ptr, SAVE_TYPE_NORMAL)) {
term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ成功!", "Panic save succeeded!"));
} else {
term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ失敗!", "Panic save failed!"));
(void)signal(SIGPWR, handle_signal_abort);
#endif
}
-
p_ptr->panic_save = 1;
signals_ignore_tstp();
(void)strcpy(p_ptr->died_from, _("(緊急セーブ)", "(panic save)"));
- (void)save_player(p_ptr);
+ (void)save_player(p_ptr, SAVE_TYPE_NORMAL);
quit(NULL);
return 0;
}
validate_dir(ANGBAND_DIR_INFO, FALSE);
validate_dir(ANGBAND_DIR_PREF, TRUE);
validate_dir(ANGBAND_DIR_SAVE, FALSE);
+ validate_dir(ANGBAND_DIR_DEBUG_SAVE, FALSE);
validate_dir(ANGBAND_DIR_USER, TRUE);
validate_dir(ANGBAND_DIR_XTRA, TRUE);
path_build(path, sizeof(path), ANGBAND_DIR_FILE, _("news_j.txt", "news.txt"));
quit(NULL);
return 0;
}
-#endif /* WINDOWS */
\ No newline at end of file
+#endif /* WINDOWS */
#include "system/system-variables.h"
#include "term/screen-processor.h"
#include "term/term-color-types.h"
+#include "time.h"
#include "util/angband-files.h"
#include "world/world.h"
string_free(ANGBAND_DIR_HELP);
string_free(ANGBAND_DIR_INFO);
string_free(ANGBAND_DIR_SAVE);
+ string_free(ANGBAND_DIR_DEBUG_SAVE);
string_free(ANGBAND_DIR_USER);
string_free(ANGBAND_DIR_XTRA);
ANGBAND_DIR_PREF = string_make(libpath);
strcpy(vartail, "save");
ANGBAND_DIR_SAVE = string_make(varpath);
+ strcpy(vartail, "save\\log");
+ ANGBAND_DIR_DEBUG_SAVE = string_make(varpath);
#ifdef PRIVATE_USER_PATH
path_build(buf, sizeof(buf), PRIVATE_USER_PATH, VERSION_NAME);
ANGBAND_DIR_USER = string_make(buf);
#endif
strcpy(libtail, "xtra");
ANGBAND_DIR_XTRA = string_make(libpath);
+
+ time_t now = time(NULL);
+ struct tm *t = localtime(&now);
+ char tmp[128];
+ strftime(tmp, sizeof(tmp), "%Y-%m-%d-%H-%M-%S", t);
+ path_build(debug_savefile, sizeof(debug_savefile), ANGBAND_DIR_DEBUG_SAVE, tmp);
+
+ struct _finddata_t c_file;
+ intptr_t hFile;
+ char log_file_expr[1024];
+ path_build(log_file_expr, sizeof(log_file_expr), ANGBAND_DIR_DEBUG_SAVE, "*-*");
+
+ if ((hFile = _findfirst(log_file_expr, &c_file)) != -1L) {
+ do {
+ if (((t->tm_yday + 365 - localtime(&c_file.time_write)->tm_yday) % 365) > 7) {
+ char c_file_fullpath[1024];
+ path_build(c_file_fullpath, sizeof(c_file_fullpath), ANGBAND_DIR_DEBUG_SAVE, c_file.name);
+ remove(c_file_fullpath);
+ }
+ } while (_findnext(hFile, &c_file) == 0);
+ _findclose(hFile);
+ }
}
/*!
#ifdef JP
/* 死んだ時に強制終了して死を回避できなくしてみた by Habu */
- if (!cheat_save && !save_player(creature_ptr))
+ if (!cheat_save && !save_player(creature_ptr, SAVE_TYPE_NORMAL))
msg_print("セーブ失敗!");
#endif
*/
void process_player_name(player_type *creature_ptr, bool sf)
{
- char old_player_base[32] = "";
- if (current_world_ptr->character_generated)
- strcpy(old_player_base, creature_ptr->base_name);
+ char old_player_base[32] = "";
+ if (current_world_ptr->character_generated)
+ strcpy(old_player_base, creature_ptr->base_name);
- for (int i = 0; creature_ptr->name[i]; i++)
- {
+ for (int i = 0; creature_ptr->name[i]; i++) {
#ifdef JP
- if (iskanji(creature_ptr->name[i]))
- {
- i++;
- continue;
- }
+ if (iskanji(creature_ptr->name[i])) {
+ i++;
+ continue;
+ }
- if (iscntrl((unsigned char)creature_ptr->name[i]))
+ if (iscntrl((unsigned char)creature_ptr->name[i]))
#else
- if (iscntrl(creature_ptr->name[i]))
+ if (iscntrl(creature_ptr->name[i]))
#endif
- {
- quit_fmt(_("'%s' という名前は不正なコントロールコードを含んでいます。", "The name '%s' contains control chars!"), creature_ptr->name);
- }
- }
-
- int k = 0;
- for (int i = 0; creature_ptr->name[i]; i++)
- {
+ {
+ quit_fmt(_("'%s' という名前は不正なコントロールコードを含んでいます。", "The name '%s' contains control chars!"), creature_ptr->name);
+ }
+ }
+
+ int k = 0;
+ for (int i = 0; creature_ptr->name[i]; i++) {
#ifdef JP
- unsigned char c = creature_ptr->name[i];
+ unsigned char c = creature_ptr->name[i];
#else
- char c = creature_ptr->name[i];
+ char c = creature_ptr->name[i];
#endif
#ifdef JP
- if (iskanji(c)) {
- if (k + 2 >= (int)sizeof(creature_ptr->base_name) || !creature_ptr->name[i + 1])
- break;
-
- creature_ptr->base_name[k++] = c;
- i++;
- creature_ptr->base_name[k++] = creature_ptr->name[i];
- }
+ if (iskanji(c)) {
+ if (k + 2 >= (int)sizeof(creature_ptr->base_name) || !creature_ptr->name[i + 1])
+ break;
+
+ creature_ptr->base_name[k++] = c;
+ i++;
+ creature_ptr->base_name[k++] = creature_ptr->name[i];
+ }
#ifdef SJIS
- else if (iskana(c)) creature_ptr->base_name[k++] = c;
+ else if (iskana(c))
+ creature_ptr->base_name[k++] = c;
#endif
- else
+ else
#endif
- if (!strncmp(PATH_SEP, creature_ptr->name + i, strlen(PATH_SEP)))
- {
- creature_ptr->base_name[k++] = '_';
- i += strlen(PATH_SEP);
- }
+ if (!strncmp(PATH_SEP, creature_ptr->name + i, strlen(PATH_SEP))) {
+ creature_ptr->base_name[k++] = '_';
+ i += strlen(PATH_SEP);
+ }
#if defined(WINDOWS)
- else if (angband_strchr("\"*,/:;<>?\\|", c))
- creature_ptr->base_name[k++] = '_';
+ else if (angband_strchr("\"*,/:;<>?\\|", c))
+ creature_ptr->base_name[k++] = '_';
#endif
- else if (isprint(c))
- creature_ptr->base_name[k++] = c;
- }
+ else if (isprint(c))
+ creature_ptr->base_name[k++] = c;
+ }
- creature_ptr->base_name[k] = '\0';
- if (!creature_ptr->base_name[0])
- strcpy(creature_ptr->base_name, "PLAYER");
+ creature_ptr->base_name[k] = '\0';
+ if (!creature_ptr->base_name[0])
+ strcpy(creature_ptr->base_name, "PLAYER");
#ifdef SAVEFILE_MUTABLE
- sf = TRUE;
+ sf = TRUE;
#endif
- if (!savefile_base[0] && savefile[0])
- {
- concptr s = savefile;
- while (TRUE)
- {
- concptr t;
- t = angband_strstr(s, PATH_SEP);
- if (!t)
- break;
- s = t + 1;
- }
-
- strcpy(savefile_base, s);
- }
-
- if (!savefile_base[0] || !savefile[0])
- sf = TRUE;
-
- if (sf)
- {
- char temp[128];
- strcpy(savefile_base, creature_ptr->base_name);
+ if (!savefile_base[0] && savefile[0]) {
+ concptr s = savefile;
+ while (TRUE) {
+ concptr t;
+ t = angband_strstr(s, PATH_SEP);
+ if (!t)
+ break;
+ s = t + 1;
+ }
+
+ strcpy(savefile_base, s);
+ }
+
+ if (!savefile_base[0] || !savefile[0])
+ sf = TRUE;
+
+ if (sf) {
+ char temp[128];
+ strcpy(savefile_base, creature_ptr->base_name);
#ifdef SAVEFILE_USE_UID
- /* Rename the savefile, using the creature_ptr->player_uid and creature_ptr->base_name */
- (void)sprintf(temp, "%d.%s", creature_ptr->player_uid, creature_ptr->base_name);
+ /* Rename the savefile, using the creature_ptr->player_uid and creature_ptr->base_name */
+ (void)sprintf(temp, "%d.%s", creature_ptr->player_uid, creature_ptr->base_name);
#else
- /* Rename the savefile, using the creature_ptr->base_name */
- (void)sprintf(temp, "%s", creature_ptr->base_name);
+ /* Rename the savefile, using the creature_ptr->base_name */
+ (void)sprintf(temp, "%s", creature_ptr->base_name);
#endif
- path_build(savefile, sizeof(savefile), ANGBAND_DIR_SAVE, temp);
- }
+ path_build(savefile, sizeof(savefile), ANGBAND_DIR_SAVE, temp);
+ }
- if (current_world_ptr->character_generated && !streq(old_player_base, creature_ptr->base_name))
- {
- autopick_load_pref(creature_ptr, FALSE);
- }
+ if (current_world_ptr->character_generated && !streq(old_player_base, creature_ptr->base_name)) {
+ autopick_load_pref(creature_ptr, FALSE);
+ }
}
-
/*!
* @brief プレイヤーの名前を変更するコマンドのメインルーチン
* Gets a name for the character, reacting to name changes.
*/
void get_name(player_type *creature_ptr)
{
- char tmp[64];
- strcpy(tmp, creature_ptr->name);
+ char tmp[64];
+ strcpy(tmp, creature_ptr->name);
- if (get_string(_("キャラクターの名前を入力して下さい: ", "Enter a name for your character: "), tmp, 15))
- {
- strcpy(creature_ptr->name, tmp);
- }
+ if (get_string(_("キャラクターの名前を入力して下さい: ", "Enter a name for your character: "), tmp, 15)) {
+ strcpy(creature_ptr->name, tmp);
+ }
- if (strlen(creature_ptr->name) == 0)
- {
- strcpy(creature_ptr->name, "PLAYER");
- }
+ if (strlen(creature_ptr->name) == 0) {
+ strcpy(creature_ptr->name, "PLAYER");
+ }
- strcpy(tmp, ap_ptr->title);
+ strcpy(tmp, ap_ptr->title);
#ifdef JP
- if (ap_ptr->no == 1)
- strcat(tmp, "の");
+ if (ap_ptr->no == 1)
+ strcat(tmp, "の");
#else
- strcat(tmp, " ");
+ strcat(tmp, " ");
#endif
- strcat(tmp, creature_ptr->name);
+ strcat(tmp, creature_ptr->name);
- term_erase(34, 1, 255);
- c_put_str(TERM_L_BLUE, tmp, 1, 34);
- clear_from(22);
-}
+ term_erase(34, 1, 255);
+ c_put_str(TERM_L_BLUE, tmp, 1, 34);
+ clear_from(22);
+}
\ No newline at end of file
* @brief ゲームオプション情報を書き込む / Write the "options"
* @return なし
*/
-void wr_options(void)
+void wr_options(save_type type)
{
for (int i = 0; i < 4; i++)
wr_u32b(0L);
if (cheat_diary_output)
c |= 0x8000;
+ if (type == SAVE_TYPE_DEBUG)
+ c |= 0xFFFF;
+
wr_u16b(c);
wr_byte(autosave_l);
previous_char.quick_ok = FALSE;
wr_byte((byte)previous_char.quick_ok);
-}
+}
\ No newline at end of file
#pragma once
+#include "save/save.h"
typedef struct store_type store_type;
void wr_store(store_type *store_ptr);
void wr_randomizer(void);
-void wr_options(void);
+void wr_options(save_type type);
void wr_ghost(void);
void save_quick_start(void);
#include "floor/wild.h"
#include "game-option/text-display-options.h"
#include "inventory/inventory-slot-types.h"
-#include "io/uid-checker.h"
#include "io/report.h"
+#include "io/uid-checker.h"
#include "monster-race/monster-race.h"
#include "monster/monster-compaction.h"
#include "object/object-kind.h"
* @param player_ptr プレーヤーへの参照ポインタ
* @return 成功すればtrue
*/
-static bool wr_savefile_new(player_type *player_ptr)
+static bool wr_savefile_new(player_type *player_ptr, save_type type)
{
compact_objects(player_ptr, 0);
compact_monsters(player_ptr, 0);
#endif
wr_randomizer();
- wr_options();
+ wr_options(type);
u32b tmp32u = message_num();
if (compress_savefile && (tmp32u > 40))
tmp32u = 40;
* @details
* Angband 2.8.0 will use "fd" instead of "fff" if possible
*/
-static bool save_player_aux(player_type *player_ptr, char *name)
+static bool save_player_aux(player_type *player_ptr, char *name, save_type type)
{
safe_setuid_grab(player_ptr);
int file_permission = 0644;
saving_savefile = angband_fopen(name, "wb");
safe_setuid_drop();
if (saving_savefile) {
- if (wr_savefile_new(player_ptr))
+ if (wr_savefile_new(player_ptr, type))
is_save_successful = TRUE;
if (angband_fclose(saving_savefile))
* @param player_ptr プレーヤーへの参照ポインタ
* @return 成功すればtrue
*/
-bool save_player(player_type *player_ptr)
+bool save_player(player_type *player_ptr, save_type type)
{
char safe[1024];
strcpy(safe, savefile);
safe_setuid_drop();
update_playtime();
bool result = FALSE;
- if (save_player_aux(player_ptr, safe)) {
+ if (save_player_aux(player_ptr, safe, type)) {
char temp[1024];
+ char filename[1024];
strcpy(temp, savefile);
strcat(temp, ".old");
safe_setuid_grab(player_ptr);
fd_kill(temp);
- fd_move(savefile, temp);
- fd_move(safe, savefile);
+
+ if (type == SAVE_TYPE_DEBUG)
+ strcpy(filename, debug_savefile);
+ if (type == SAVE_TYPE_NORMAL)
+ strcpy(filename, savefile);
+
+ fd_move(filename, temp);
+ fd_move(safe, filename);
fd_kill(temp);
safe_setuid_drop();
current_world_ptr->character_loaded = TRUE;
}
return result;
-}
+}
\ No newline at end of file
#include "floor/floor-save.h"
#include "system/angband.h"
-bool save_player(player_type *player_ptr);
+typedef enum save_type {
+ SAVE_TYPE_NORMAL = 0,
+ SAVE_TYPE_DEBUG = 1
+}save_type;
+
+bool save_player(player_type *player_ptr, save_type type);
void term_queue_line(TERM_LEN x, TERM_LEN y, int n, TERM_COLOR *a, char *c, TERM_COLOR *ta, char *tc);
bool need_term_fresh(player_type *player_ptr);
+bool macro_running(void);
errr term_fresh(void);
errr term_set_cursor(int v);