7 #include "cmd-io/cmd-process-screen.h"
8 #include "cmd-visual/cmd-draw.h"
9 #include "core/asking-player.h"
10 #include "core/player-redraw-types.h"
11 #include "core/stuff-handler.h"
12 #include "core/visuals-reseter.h"
13 #include "game-option/special-options.h"
14 #include "io/files-util.h"
15 #include "io/input-key-acceptor.h"
16 #include "term/gameterm.h"
17 #include "term/screen-processor.h"
18 #include "term/term-color-types.h"
19 #include "util/angband-files.h"
20 #include "view/display-messages.h"
22 // Encode the screen colors
23 static char hack[17] = "dwsorgbuDWvyRGBU";
25 static concptr tags[4] = { "HEADER_START:", "HEADER_END:", "FOOTER_START:", "FOOTER_END:", };
26 static concptr html_head[3] = { "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n", "<pre>", 0, };
27 static concptr html_foot[3] = { "</pre>\n", "</body>\n</html>\n", 0, };
30 * todo io/ 以下に移したいところだが、このファイルの行数も大したことがないので一旦保留
31 * @brief 一時ファイルを読み込み、ファイルに書き出す
32 * @param fff ファイルへの参照ポインタ
33 * @param tempfff 一時ファイルへの参照ポインタ
35 * @param buf_size バッファサイズ
38 static void read_temporary_file(FILE *fff, FILE *tmpfff, char buf[], size_t buf_size, int num_tag)
40 bool is_first_line = TRUE;
41 int next_tag = num_tag + 1;
42 while (!angband_fgets(tmpfff, buf, buf_size))
46 if (strncmp(buf, tags[num_tag], strlen(tags[num_tag])) == 0)
47 is_first_line = FALSE;
52 if (strncmp(buf, tags[next_tag], strlen(tags[next_tag])) == 0)
55 fprintf(fff, "%s\n", buf);
64 * @param fff 記念撮影ファイルへの参照ポインタ
67 static void screen_dump_one_line(int wid, int y, FILE *fff)
69 TERM_COLOR a = 0, old_a = 0;
71 for (TERM_LEN x = 0; x < wid - 1; x++)
74 (void)(term_what(x, y, &a, &c));
77 case '&': cc = "&"; break;
78 case '<': cc = "<"; break;
79 case '>': cc = ">"; break;
81 case 0x1f: c = '.'; break;
82 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
87 if ((y == 0 && x == 0) || a != old_a)
89 int rv = angband_color_table[a][1];
90 int gv = angband_color_table[a][2];
91 int bv = angband_color_table[a][3];
92 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
93 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
98 fprintf(fff, "%s", cc);
100 fprintf(fff, "%c", c);
106 * @brief 記念撮影を行方向にスイープする
109 * @param fff 記念撮影ファイルへの参照ポインタ
112 static void screen_dump_lines(int wid, int hgt, FILE *fff)
114 for (TERM_LEN y = 0; y < hgt; y++)
119 screen_dump_one_line(wid, y, fff);
125 * @brief ファイルへ書き込めない場合にエラーを表示する
126 * @param fff ダンプファイルへの参照ポインタ
128 * @return ファイルへ書き込めるならTRUE、書き込めないならFALSE
130 static bool check_screen_html_can_open(FILE *fff, char *filename, int message)
132 if (fff) return TRUE;
133 if (message == 0) return FALSE;
135 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
142 * @brief HTMLヘッダを書き込む
143 * @param tmpfff 一時ファイルへの参照ポインタ
144 * @param fff 記念撮影ファイルへの参照ポインタ
146 * @param buf_size バッファサイズ
148 static void write_html_header(FILE *tmpfff, FILE *fff, char buf[], size_t buf_size)
152 read_temporary_file(fff, tmpfff, buf, buf_size, 0);
156 for (int i = 0; html_head[i]; i++)
157 fputs(html_head[i], fff);
162 * @brief HTMLフッタを書き込む
163 * @param tmpfff 一時ファイルへの参照ポインタ
164 * @param fff 記念撮影ファイルへの参照ポインタ
166 * @param buf_size バッファサイズ
168 static void write_html_footer(FILE *tmpfff, FILE *fff, char buf[], size_t buf_size)
170 fprintf(fff, "</font>");
173 for (int i = 0; html_foot[i]; i++)
174 fputs(html_foot[i], fff);
179 read_temporary_file(fff, tmpfff, buf, buf_size, 2);
180 angband_fclose(tmpfff);
187 void do_cmd_save_screen_html_aux(char *filename, int message)
190 term_get_size(&wid, &hgt);
192 fff = angband_fopen(filename, "w");
193 if (!check_screen_html_can_open(fff, filename, message)) return;
195 if (message) screen_save();
198 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
200 tmpfff = angband_fopen(buf, "r");
201 write_html_header(tmpfff, fff, buf, sizeof(buf));
202 screen_dump_lines(wid, hgt, fff);
203 write_html_footer(tmpfff, fff, buf, sizeof(buf));
207 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
217 * @brief HTML方式で記念撮影する / Save a screen dump to a file
221 static void do_cmd_save_screen_html(void)
223 char buf[1024], tmp[256] = "screen.html";
225 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
227 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
231 do_cmd_save_screen_html_aux(buf, 1);
236 * @brief 記念撮影の方式を問い合わせる
237 * @param html_dump HTMLダンプするか否か
238 * @return ダンプするならTRUE、キャンセルならFALSE
240 static bool ask_html_dump(bool *html_dump)
245 if (c == 'Y' || c == 'y')
251 if (c == 'H' || c == 'h')
267 * @brief ファイルへ書き込めない場合にエラーを表示する
268 * @param fff ダンプファイルへの参照ポインタ
270 * @return ファイルへ書き込めるならTRUE、書き込めないならFALSE
272 static bool check_screen_text_can_open(FILE *fff, char buf[])
274 if (fff) return TRUE;
276 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
283 * todo どこかバグっていて、(恐らく初期化されていない)変な文字列まで出力される
284 * @brief テキスト方式で記念撮影する
287 * @return 記念撮影に成功したらTRUE、ファイルが開けなかったらFALSE
289 static bool do_cmd_save_screen_text(int wid, int hgt)
295 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
296 fff = angband_fopen(buf, "w");
297 if (!check_screen_text_can_open(fff, buf)) return FALSE;
300 for (TERM_LEN y = 0; y < hgt; y++)
303 for (x = 0; x < wid - 1; x++)
305 (void)(term_what(x, y, &a, &c));
310 fprintf(fff, "%s\n", buf);
314 for (TERM_LEN y = 0; y < hgt; y++)
317 for (x = 0; x < wid - 1; x++)
319 (void)(term_what(x, y, &a, &c));
320 buf[x] = hack[a & 0x0F];
324 fprintf(fff, "%s\n", buf);
329 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
337 * @brief 記念撮影のためにグラフィック使用をOFFにする
338 * @param creature_ptr プレーヤーへの参照ポインタ
339 * @param handle_stuff 画面更新用の関数ポインタ
340 * @return 記念撮影直前のグラフィックオプション
342 static bool update_use_graphics(player_type *creature_ptr, void(*process_autopick_file_command)(char*))
344 if (!use_graphics) return TRUE;
346 use_graphics = FALSE;
347 reset_visuals(creature_ptr, process_autopick_file_command);
348 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
349 handle_stuff(creature_ptr);
355 * Save a screen dump to a file
356 * @param creature_ptr プレーヤーへの参照ポインタ
357 * @param handle_stuff 画面更新用の関数ポインタ
360 void do_cmd_save_screen(player_type *creature_ptr, void(*process_autopick_file_command)(char*))
362 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
364 if (!ask_html_dump(&html_dump)) return;
367 term_get_size(&wid, &hgt);
369 bool old_use_graphics = update_use_graphics(creature_ptr, process_autopick_file_command);
373 do_cmd_save_screen_html();
374 do_cmd_redraw(creature_ptr);
376 else if (!do_cmd_save_screen_text(wid, hgt))
381 if (old_use_graphics) return;
384 reset_visuals(creature_ptr, process_autopick_file_command);
385 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
386 handle_stuff(creature_ptr);
391 * @brief 白文字だけ画面に描画する (todo 目的は不明瞭)
393 * @param fff 記念撮影ファイルへの参照ポインタ
396 * @return ファイルが読み込めなくなったらFALSEで抜ける
398 static bool draw_white_characters(char buf[], FILE *fff, int wid, int hgt)
401 for (TERM_LEN y = 0; okay; y++)
403 if (!fgets(buf, 1024, fff)) okay = FALSE;
405 if (buf[0] == '\n' || buf[0] == '\0') break;
406 if (y >= hgt) continue;
408 for (TERM_LEN x = 0; x < wid - 1; x++)
410 if (buf[x] == '\n' || buf[x] == '\0') break;
412 term_draw(x, y, TERM_WHITE, buf[x]);
421 * @brief 白以外の文字を画面に描画する (todo 目的は不明瞭)
423 * @param fff 記念撮影ファイルへの参照ポインタ
426 * @param 白文字が途中で読み込めなくなっていたらTRUE
429 static void draw_colored_characters(char buf[], FILE *fff, int wid, int hgt, bool okay)
431 TERM_COLOR a = TERM_DARK;
433 for (TERM_LEN y = 0; okay; y++)
435 if (!fgets(buf, 1024, fff)) okay = FALSE;
437 if (buf[0] == '\n' || buf[0] == '\0') break;
438 if (y >= hgt) continue;
440 for (TERM_LEN x = 0; x < wid - 1; x++)
442 if (buf[x] == '\n' || buf[x] == '\0') break;
444 (void)(term_what(x, y, &a, &c));
445 for (int i = 0; i < 16; i++)
447 if (hack[i] == buf[x]) a = (byte)i;
450 term_draw(x, y, a, c);
457 * @brief Load a screen dump from a file
461 void do_cmd_load_screen(void)
466 term_get_size(&wid, &hgt);
467 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
468 fff = angband_fopen(buf, "r");
471 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
478 bool okay = draw_white_characters(buf, fff, wid, hgt);
479 draw_colored_characters(buf, fff, wid, hgt, okay);
482 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);