OSDN Git Service

[Style] Apply clang-format to all *.cpp files
[hengbandforosx/hengbandosx.git] / src / cmd-io / cmd-macro.cpp
1 #include "cmd-io/cmd-macro.h"
2 #include "cmd-io/cmd-gameoption.h"
3 #include "cmd-io/macro-util.h"
4 #include "core/asking-player.h"
5 #include "game-option/input-options.h"
6 #include "io/files-util.h"
7 #include "io/input-key-acceptor.h"
8 #include "io/input-key-requester.h"
9 #include "io/read-pref-file.h"
10 #include "main/sound-of-music.h"
11 #include "system/player-type-definition.h"
12 #include "term/screen-processor.h"
13 #include "term/term-color-types.h"
14 #include "util/angband-files.h"
15 #include "util/int-char-converter.h"
16 #include "util/string-processor.h"
17 #include "view/display-messages.h"
18
19 /*!
20  * @brief マクロ情報をprefファイルに保存する /
21  * @param fname ファイル名
22  */
23 static void macro_dump(FILE **fpp, concptr fname)
24 {
25     static concptr mark = "Macro Dump";
26     char buf[1024];
27     path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
28     if (!open_auto_dump(fpp, buf, mark)) {
29         return;
30     }
31
32     auto_dump_printf(*fpp, _("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
33
34     for (int i = 0; i < macro__num; i++) {
35         ascii_to_text(buf, macro__act[i]);
36         auto_dump_printf(*fpp, "A:%s\n", buf);
37         ascii_to_text(buf, macro__pat[i]);
38         auto_dump_printf(*fpp, "P:%s\n", buf);
39         auto_dump_printf(*fpp, "\n");
40     }
41
42     close_auto_dump(fpp, mark);
43 }
44
45 /*!
46  * @brief マクロのトリガーキーを取得する /
47  * Hack -- ask for a "trigger" (see below)
48  * @param buf キー表記を保管するバッファ
49  * @details
50  * <pre>
51  * Note the complex use of the "inkey()" function from "util.c".
52  *
53  * Note that both "flush()" calls are extremely important.
54  * </pre>
55  */
56 static void do_cmd_macro_aux(char *buf)
57 {
58     flush();
59     inkey_base = true;
60     char i = inkey();
61     int n = 0;
62     while (i) {
63         buf[n++] = i;
64         inkey_base = true;
65         inkey_scan = true;
66         i = inkey();
67     }
68
69     buf[n] = '\0';
70     flush();
71     char tmp[1024];
72     ascii_to_text(tmp, buf);
73     term_addstr(-1, TERM_WHITE, tmp);
74 }
75
76 /*!
77  * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
78  * Hack -- ask for a keymap "trigger" (see below)
79  * @param buf キー表記を取得するバッファ
80  * @details
81  * <pre>
82  * Note that both "flush()" calls are extremely important.  This may
83  * no longer be true, since "util.c" is much simpler now.
84  * </pre>
85  */
86 static void do_cmd_macro_aux_keymap(char *buf)
87 {
88     char tmp[1024];
89     flush();
90     buf[0] = inkey();
91     buf[1] = '\0';
92     ascii_to_text(tmp, buf);
93     term_addstr(-1, TERM_WHITE, tmp);
94     flush();
95 }
96
97 /*!
98  * @brief キーマップをprefファイルにダンプする /
99  * Hack -- append all keymaps to the given file
100  * @param fname ファイルネーム
101  * @return エラーコード
102  * @details
103  */
104 static errr keymap_dump(concptr fname)
105 {
106     FILE *auto_dump_stream;
107     static concptr mark = "Keymap Dump";
108     char key[1024];
109     char buf[1024];
110     BIT_FLAGS mode;
111     if (rogue_like_commands) {
112         mode = KEYMAP_MODE_ROGUE;
113     } else {
114         mode = KEYMAP_MODE_ORIG;
115     }
116
117     path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
118     if (!open_auto_dump(&auto_dump_stream, buf, mark)) {
119         return -1;
120     }
121
122     auto_dump_printf(auto_dump_stream, _("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
123     for (int i = 0; i < 256; i++) {
124         concptr act;
125         act = keymap_act[mode][i];
126         if (!act) {
127             continue;
128         }
129
130         buf[0] = (char)i;
131         buf[1] = '\0';
132         ascii_to_text(key, buf);
133         ascii_to_text(buf, act);
134         auto_dump_printf(auto_dump_stream, "A:%s\n", buf);
135         auto_dump_printf(auto_dump_stream, "C:%d:%s\n", mode, key);
136     }
137
138     close_auto_dump(&auto_dump_stream, mark);
139     return 0;
140 }
141
142 /*!
143  * @brief マクロを設定するコマンドのメインルーチン /
144  * Interact with "macros"
145  * @details
146  * <pre>
147  * Note that the macro "action" must be defined before the trigger.
148  *
149  * Could use some helpful instructions on this page.
150  * </pre>
151  */
152 void do_cmd_macros(PlayerType *player_ptr)
153 {
154     char tmp[1024];
155     char buf[1024];
156     static char macro_buf[1024];
157     FILE *auto_dump_stream;
158     BIT_FLAGS mode = rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;
159     screen_save();
160     term_clear();
161
162     auto print_macro_menu = [] {
163         prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
164         prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
165         prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
166         prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
167         prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
168         prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
169         prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
170         prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
171         prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
172         prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
173         prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
174     };
175     print_macro_menu();
176
177     while (true) {
178         msg_print(_("コマンド: ", "Command: "));
179         const int key = inkey();
180         if (key == ESCAPE) {
181             break;
182         }
183         clear_from(1);
184         print_macro_menu();
185
186         if (key == '1') {
187             prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
188             prt(_("ファイル: ", "File: "), 18, 0);
189             sprintf(tmp, "%s.prf", player_ptr->base_name);
190             if (!askfor(tmp, 80)) {
191                 continue;
192             }
193
194             errr err = process_pref_file(player_ptr, tmp, true);
195             if (-2 == err) {
196                 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
197             } else if (err) {
198                 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
199             } else {
200                 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
201             }
202         } else if (key == '2') {
203             prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
204             prt(_("ファイル: ", "File: "), 18, 0);
205             sprintf(tmp, "%s.prf", player_ptr->base_name);
206             if (!askfor(tmp, 80)) {
207                 continue;
208             }
209
210             macro_dump(&auto_dump_stream, tmp);
211             msg_print(_("マクロを追加しました。", "Appended macros."));
212         } else if (key == '3') {
213             prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
214             prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
215             prt(_("トリガーキー: ", "Trigger: "), 18, 0);
216             do_cmd_macro_aux(buf);
217             int k = macro_find_exact(buf);
218             if (k < 0) {
219                 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
220             } else {
221                 // マクロの作成時に参照するためmacro_bufにコピーする
222                 strncpy(macro_buf, macro__act[k].c_str(), sizeof(macro_buf) - 1);
223                 // too long macro must die
224                 strncpy(tmp, macro_buf, 80);
225                 tmp[80] = '\0';
226                 ascii_to_text(buf, tmp);
227                 prt(buf, 22, 0);
228                 msg_print(_("マクロを確認しました。", "Found a macro."));
229             }
230         } else if (key == '4') {
231             prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
232             prt(_("トリガーキー: ", "Trigger: "), 18, 0);
233             do_cmd_macro_aux(buf);
234             c_prt(TERM_L_RED,
235                 _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
236                     "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."),
237                 22, 0);
238             prt(_("マクロ行動: ", "Action: "), 20, 0);
239             // 最後に参照したマクロデータを元に作成する(コピーを行えるように)
240             macro_buf[80] = '\0';
241             ascii_to_text(tmp, macro_buf);
242             if (askfor(tmp, 80)) {
243                 text_to_ascii(macro_buf, tmp);
244                 macro_add(buf, macro_buf);
245                 msg_print(_("マクロを追加しました。", "Added a macro."));
246             }
247         } else if (key == '5') {
248             prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
249             prt(_("トリガーキー: ", "Trigger: "), 18, 0);
250             do_cmd_macro_aux(buf);
251             macro_add(buf, buf);
252             msg_print(_("マクロを削除しました。", "Removed a macro."));
253         } else if (key == '6') {
254             prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
255             prt(_("ファイル: ", "File: "), 18, 0);
256             sprintf(tmp, "%s.prf", player_ptr->base_name);
257             if (!askfor(tmp, 80)) {
258                 continue;
259             }
260
261             (void)keymap_dump(tmp);
262             msg_print(_("キー配置を追加しました。", "Appended keymaps."));
263         } else if (key == '7') {
264             prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
265             prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
266             prt(_("押すキー: ", "Keypress: "), 18, 0);
267             do_cmd_macro_aux_keymap(buf);
268             concptr act = keymap_act[mode][(byte)(buf[0])];
269             if (!act) {
270                 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
271             } else {
272                 // マクロの作成時に参照するためmacro_bufにコピーする
273                 strncpy(macro_buf, act, sizeof(macro_buf) - 1);
274                 // too long macro must die
275                 strncpy(tmp, macro_buf, 80);
276                 tmp[80] = '\0';
277                 ascii_to_text(buf, tmp);
278                 prt(buf, 22, 0);
279                 msg_print(_("キー配置を確認しました。", "Found a keymap."));
280             }
281         } else if (key == '8') {
282             prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
283             prt(_("押すキー: ", "Keypress: "), 18, 0);
284             do_cmd_macro_aux_keymap(buf);
285             c_prt(TERM_L_RED,
286                 _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
287                     "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."),
288                 22, 0);
289             prt(_("行動: ", "Action: "), 20, 0);
290             // 最後に参照したマクロデータを元に作成する(コピーを行えるように)
291             macro_buf[80] = '\0';
292             ascii_to_text(tmp, macro_buf);
293             if (askfor(tmp, 80)) {
294                 text_to_ascii(macro_buf, tmp);
295                 string_free(keymap_act[mode][(byte)(buf[0])]);
296                 keymap_act[mode][(byte)(buf[0])] = string_make(macro_buf);
297                 msg_print(_("キー配置を追加しました。", "Added a keymap."));
298             }
299         } else if (key == '9') {
300             prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
301             prt(_("押すキー: ", "Keypress: "), 18, 0);
302             do_cmd_macro_aux_keymap(buf);
303             string_free(keymap_act[mode][(byte)(buf[0])]);
304             keymap_act[mode][(byte)(buf[0])] = nullptr;
305             msg_print(_("キー配置を削除しました。", "Removed a keymap."));
306         } else if (key == '0') {
307             prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
308             c_prt(TERM_L_RED,
309                 _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
310                     "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."),
311                 22, 0);
312             prt(_("マクロ行動: ", "Action: "), 20, 0);
313             buf[0] = '\0';
314             if (!askfor(buf, 80)) {
315                 continue;
316             }
317
318             text_to_ascii(macro_buf, buf);
319         } else {
320             bell();
321         }
322
323         msg_erase();
324     }
325
326     screen_load();
327 }