OSDN Git Service

[Refactor] format 関数の戻り値を std::string にする
[hengbandforosx/hengbandosx.git] / src / term / screen-processor.cpp
1 #include "term/screen-processor.h"
2 #include "io/input-key-acceptor.h"
3 #include "term/term-color-types.h"
4 #include "view/display-messages.h"
5 #include "world/world.h"
6
7 /*
8  * Hack -- prevent "accidents" in "screen_save()" or "screen_load()"
9  */
10 static int screen_depth = 0;
11
12 /*
13  * Move the cursor
14  */
15 void move_cursor(int row, int col)
16 {
17     term_gotoxy(col, row);
18 }
19
20 /*
21  * Flush all input chars.  Actually, remember the flush,
22  * and do a "special flush" before the next "inkey()".
23  *
24  * This is not only more efficient, but also necessary to make sure
25  * that various "inkey()" codes are not "lost" along the way.
26  */
27 void flush(void)
28 {
29     inkey_xtra = true;
30 }
31
32 /*
33  * Save the screen, and increase the "icky" depth.
34  *
35  * This function must match exactly one call to "screen_load()".
36  */
37 void screen_save()
38 {
39     msg_print(nullptr);
40
41     term_save();
42
43     w_ptr->character_icky_depth++;
44     screen_depth++;
45 }
46
47 /*
48  * Load the screen, and decrease the "icky" depth.
49  *
50  * This function must match exactly one call to "screen_save()".
51  */
52 void screen_load(ScreenLoadOptType opt)
53 {
54     msg_print(nullptr);
55
56     switch (opt) {
57     case ScreenLoadOptType::ONE:
58         term_load(false);
59         w_ptr->character_icky_depth--;
60         screen_depth--;
61         break;
62
63     case ScreenLoadOptType::ALL:
64         term_load(true);
65         w_ptr->character_icky_depth -= static_cast<byte>(screen_depth);
66         screen_depth = 0;
67         break;
68
69     default:
70         break;
71     }
72 }
73
74 /*
75  * Display a string on the screen using an attribute.
76  *
77  * At the given location, using the given attribute, if allowed,
78  * add the given string.  Do not clear the line.
79  */
80 void c_put_str(TERM_COLOR attr, std::string_view sv, TERM_LEN row, TERM_LEN col)
81 {
82     term_putstr(col, row, -1, attr, sv);
83 }
84
85 /*
86  * As above, but in "white"
87  */
88 void put_str(std::string_view sv, TERM_LEN row, TERM_LEN col)
89 {
90     term_putstr(col, row, -1, TERM_WHITE, sv);
91 }
92
93 /*
94  * Display a string on the screen using an attribute, and clear
95  * to the end of the line.
96  */
97 void c_prt(TERM_COLOR attr, std::string_view sv, TERM_LEN row, TERM_LEN col)
98 {
99     term_erase(col, row, 255);
100     term_addstr(-1, attr, sv);
101 }
102
103 /*
104  * As above, but in "white"
105  */
106 void prt(std::string_view sv, TERM_LEN row, TERM_LEN col)
107 {
108     /* Spawn */
109     c_prt(TERM_WHITE, sv, row, col);
110 }
111
112 /*
113  * Print some (colored) text to the screen at the current cursor position,
114  * automatically "wrapping" existing text (at spaces) when necessary to
115  * avoid placing any text into the last column, and clearing every line
116  * before placing any text in that line.  Also, allow "newline" to force
117  * a "wrap" to the next line.  Advance the cursor as needed so sequential
118  * calls to this function will work correctly.
119  *
120  * Once this function has been called, the cursor should not be moved
121  * until all the related "c_roff()" calls to the window are complete.
122  *
123  * This function will correctly handle any width up to the maximum legal
124  * value of 256, though it works best for a standard 80 character width.
125  */
126 void c_roff(TERM_COLOR a, std::string_view str)
127 {
128     int w, h;
129     (void)term_get_size(&w, &h);
130
131     int x, y;
132     (void)term_locate(&x, &y);
133
134     if (y == h - 1 && x > w - 3) {
135         return;
136     }
137
138     for (auto s = str.data(); *s != '\0'; ++s) {
139         char ch;
140 #ifdef JP
141         int k_flag = iskanji(*s);
142 #endif
143         if (*s == '\n') {
144             x = 0;
145             y++;
146             if (y == h) {
147                 break;
148             }
149
150             term_erase(x, y, 255);
151             break;
152         }
153
154 #ifdef JP
155         ch = ((k_flag || isprint(*s)) ? *s : ' ');
156 #else
157         ch = (isprint(*s) ? *s : ' ');
158 #endif
159
160 #ifdef JP
161         if ((x >= ((k_flag) ? w - 2 : w - 1)) && (ch != ' '))
162 #else
163         if ((x >= w - 1) && (ch != ' '))
164 #endif
165         {
166             int i, n = 0;
167             const int end_col = x - 1;
168
169             TERM_COLOR av[256];
170             char cv[256];
171             if (x < w) {
172 #ifdef JP
173                 /* 現在が半角文字の場合 */
174                 if (!k_flag)
175 #endif
176                 {
177                     for (i = 0; i <= end_col; i++) {
178                         term_what(i, y, &av[i], &cv[i]);
179
180                         if (cv[i] == ' ') {
181                             n = i + 1;
182                         }
183 #ifdef JP
184                         if (iskanji(cv[i])) {
185                             n = i + 2;
186                             i++;
187                             term_what(i, y, &av[i], &cv[i]);
188                         }
189 #endif
190                     }
191                 }
192 #ifdef JP
193                 else {
194                     /* 現在が全角文字のとき */
195                     /* 文頭が「。」「、」等になるときは、その1つ前の語で改行 */
196                     if (strncmp(s, "。", 2) == 0 || strncmp(s, "、", 2) == 0) {
197                         term_what(x - 1, y, &av[x - 1], &cv[x - 1]);
198                         term_what(x - 2, y, &av[x - 2], &cv[x - 2]);
199                         n = x - 2;
200                     }
201                 }
202 #endif
203             }
204             if (n == 0) {
205                 n = w;
206             }
207
208             term_erase(n, y, 255);
209             x = 0;
210             y++;
211             if (y == h) {
212                 break;
213             }
214
215             term_erase(x, y, 255);
216             for (i = n; i <= end_col; i++) {
217 #ifdef JP
218                 if (cv[i] == '\0') {
219                     break;
220                 }
221 #endif
222                 term_addch(av[i], cv[i]);
223                 if (++x > w) {
224                     x = w;
225                 }
226             }
227         }
228
229 #ifdef JP
230         term_addch((byte)(a | 0x10), ch);
231 #else
232         term_addch(a, ch);
233 #endif
234
235 #ifdef JP
236         if (k_flag) {
237             s++;
238             x++;
239             ch = *s;
240             term_addch((byte)(a | 0x20), ch);
241         }
242 #endif
243
244         if (++x > w) {
245             x = w;
246         }
247     }
248 }
249
250 /*
251  * As above, but in "white"
252  */
253 void roff(std::string_view str)
254 {
255     /* Spawn */
256     c_roff(TERM_WHITE, str);
257 }
258
259 /*
260  * Clear part of the screen
261  */
262 void clear_from(int row)
263 {
264     for (int y = row; y < game_term->hgt; y++) {
265         term_erase(0, y, 255);
266     }
267 }