OSDN Git Service

Merge branch 'master' of https://github.com/hengband/hengband
[hengbandforosx/hengbandosx.git] / src / term / gameterm.cpp
1 #include "term/gameterm.h"
2 #include "effect/attribute-types.h"
3 #include "system/system-variables.h"
4 #include "term/term-color-types.h"
5 #include "util/quarks.h"
6 #include "util/string-processor.h"
7 #include <span>
8
9 /*
10  * Convert an "attr"/"char" pair into a "pict" (P)
11  */
12 #define PICT(A, C) ((((uint16_t)(A)) << 8) | ((byte)(C)))
13
14 /*
15  * Standard window names
16  */
17 const char angband_term_name[8][16] = {
18     "Hengband",
19     "Term-1",
20     "Term-2",
21     "Term-3",
22     "Term-4",
23     "Term-5",
24     "Term-6",
25     "Term-7"
26 };
27
28 /*
29  * Global table of color definitions
30  */
31 byte angband_color_table[256][4] = {
32     { 0x00, 0x00, 0x00, 0x00 }, /* TERM_DARK */
33     { 0x00, 0xFF, 0xFF, 0xFF }, /* TERM_WHITE */
34     { 0x00, 0x80, 0x80, 0x80 }, /* TERM_SLATE */
35     { 0x00, 0xFF, 0x80, 0x00 }, /* TERM_ORANGE */
36     { 0x00, 0xC0, 0x00, 0x00 }, /* TERM_RED */
37     { 0x00, 0x00, 0x80, 0x40 }, /* TERM_GREEN */
38     { 0x00, 0x00, 0x80, 0xFF }, /* TERM_BLUE */
39     { 0x00, 0x80, 0x40, 0x00 }, /* TERM_UMBER */
40     { 0x00, 0x40, 0x40, 0x40 }, /* TERM_L_DARK */
41     { 0x00, 0xC0, 0xC0, 0xC0 }, /* TERM_L_WHITE */
42     { 0x00, 0xFF, 0x00, 0xFF }, /* TERM_VIOLET */
43     { 0x00, 0xFF, 0xFF, 0x00 }, /* TERM_YELLOW */
44     { 0x00, 0xFF, 0x00, 0x00 }, /* TERM_L_RED */
45     { 0x00, 0x00, 0xFF, 0x00 }, /* TERM_L_GREEN */
46     { 0x00, 0x00, 0xFF, 0xFF }, /* TERM_L_BLUE */
47     { 0x00, 0xC0, 0x80, 0x40 } /* TERM_L_UMBER */
48 };
49
50 /*!
51  * @brief 色名称テーブル / Hack -- the "basic" color names (see "TERM_xxx")
52  */
53 const concptr color_names[16] = {
54 #ifdef JP
55     "黒",
56     "白",
57     "青灰色",
58     "オレンジ",
59     "赤",
60     "緑",
61     "青",
62     "琥珀色",
63     "灰色",
64     "明青灰色",
65     "紫",
66     "黄",
67     "明るい赤",
68     "明るい緑",
69     "明るい青",
70     "明琥珀色",
71 #else
72     "Dark",
73     "White",
74     "Slate",
75     "Orange",
76     "Red",
77     "Green",
78     "Blue",
79     "Umber",
80     "Light Dark",
81     "Light Slate",
82     "Violet",
83     "Yellow",
84     "Light Red",
85     "Light Green",
86     "Light Blue",
87     "Light Umber",
88 #endif
89 };
90
91 /*!
92  * @brief サブウィンドウ名称テーブル
93  * @details
94  * <pre>
95  * Certain "screens" always use the main screen, including News, Birth,
96  * Dungeon, Tomb-stone, High-scores, Macros, Colors, Visuals, Options.
97  *
98  * Later, special flags may allow sub-windows to "steal" stuff from the
99  * main window, including File dump (help), File dump (artifacts, uniques),
100  * Character screen, Small scale map, Previous Messages, Store screen, etc.
101  *
102  * The "ctrl-i" (tab) command flips the "Display inven/equip" and "Display
103  * equip/inven" flags for all windows.
104  *
105  * The "ctrl-g" command (or pseudo-command) should perhaps grab a snapshot
106  * of the main screen into any interested windows.
107  * </pre>
108  */
109 const concptr window_flag_desc[32] = {
110     _("持ち物/装備一覧", "Display inven/equip"),
111     _("装備/持ち物一覧", "Display equip/inven"),
112     _("呪文一覧", "Display spell list"),
113     _("キャラクタ情報", "Display character"),
114     _("視界内のモンスター表示", "Display monsters in sight"),
115     _("ペット一覧", "Display pets"),
116     _("メッセージ", "Display messages"),
117     _("ダンジョン全体図", "Display overhead view"),
118     _("モンスターの思い出", "Display monster recall"),
119     _("アイテムの詳細", "Display object recall"),
120     _("自分の周囲を表示", "Display dungeon view"),
121     _("記念撮影", "Display snap-shot"),
122     _("足元/床上のアイテム一覧", "Display items on grid"),
123     _("発見済みのアイテム一覧", "Display found items"),
124     nullptr,
125     nullptr,
126     nullptr,
127     nullptr,
128     nullptr,
129     nullptr,
130     nullptr,
131     nullptr,
132     nullptr,
133     nullptr,
134     nullptr,
135     nullptr,
136     nullptr,
137     nullptr,
138     nullptr,
139     nullptr,
140     nullptr,
141     nullptr
142 };
143
144 /*!
145  * @brief シンボル解説テーブル /
146  * The table of "symbol info" -- each entry is a string of the form "X:desc" where "X" is the trigger, and "desc" is the "info".
147  */
148 const concptr ident_info[] = {
149 #ifdef JP
150     " :暗闇",
151     "!:薬, オイル",
152     "\":アミュレット, 頸飾り",
153     "#:壁(隠しドア)/植物/気体",
154     "$:財宝(金か宝石)",
155     "%:鉱脈(溶岩か石英)",
156     "&:箱",
157     "':開いたドア",
158     "(:軟らかい防具",
159     "):盾",
160     "*:財宝を含んだ鉱脈または球形の怪物",
161     "+:閉じたドア",
162     ",:食べ物, おばけキノコ",
163     "-:魔法棒, ロッド",
164     ".:床",
165     "/:竿状武器(アックス/パイク/等)",
166     "0:博物館の入口",
167     "1:雑貨屋の入口",
168     "2:防具屋の入口",
169     "3:武器専門店の入口",
170     "4:寺院の入口",
171     "5:錬金術の店の入口",
172     "6:魔法の店の入口",
173     "7:ブラックマーケットの入口",
174     "8:我が家の入口",
175     "9:書店の入口",
176     "::岩石",
177     ";:守りのルーン/爆発のルーン",
178     "<:上り階段",
179     "=:指輪",
180     ">:下り階段",
181     "?:巻物",
182     "@:プレイヤー",
183     "A:天使",
184     "B:鳥",
185     "C:犬",
186     "D:古代ドラゴン/ワイアーム",
187     "E:エレメンタル",
188     "F:トンボ",
189     "G:ゴースト",
190     "H:雑種",
191     "I:昆虫",
192     "J:ヘビ",
193     "K:キラー・ビートル",
194     "L:リッチ",
195     "M:多首の爬虫類",
196     "N:謎の生物",
197     "O:オーガ",
198     "P:巨大人間型生物",
199     "Q:クイルスルグ(脈打つ肉塊)",
200     "R:爬虫類/両生類",
201     "S:蜘蛛/サソリ/ダニ",
202     "T:トロル",
203     "U:上級デーモン",
204     "V:バンパイア",
205     "W:ワイト/レイス/等",
206     "X:ゾーン/ザレン/等",
207     "Y:イエティ",
208     "Z:ハウンド",
209     "[:堅いアーマー",
210     "\\:鈍器(メイス/ムチ/等)",
211     "]:種々の防具",
212     "^:トラップ",
213     "_:杖",
214     "`:人形,彫像",
215     "a:アリ",
216     "b:コウモリ",
217     "c:ムカデ",
218     "d:ドラゴン",
219     "e:目玉",
220     "f:ネコ",
221     "g:ゴーレム",
222     "h:ホビット/エルフ/ドワーフ",
223     "i:ベトベト",
224     "j:ゼリー",
225     "k:コボルド",
226     "l:水棲生物",
227     "m:モルド",
228     "n:ナーガ",
229     "o:オーク",
230     "p:人間",
231     "q:四足獣",
232     "r:ネズミ",
233     "s:スケルトン",
234     "t:町の人",
235     "u:下級デーモン",
236     "v:ボルテックス",
237     "w:イモムシ/大群",
238     /* "x:unused", */
239     "y:イーク",
240     "z:ゾンビ/ミイラ",
241     "{:飛び道具の弾(矢/弾)",
242     "|:刀剣類(ソード/ダガー/等)",
243     "}:飛び道具(弓/クロスボウ/スリング)",
244     "~:水/溶岩流(種々のアイテム)",
245 #else
246     " :A dark grid",
247     "!:A potion (or oil)",
248     "\":An amulet (or necklace)",
249     "#:A wall (or secret door) / a plant / a gas",
250     "$:Treasure (gold or gems)",
251     "%:A vein (magma or quartz)",
252     "&:A chest",
253     "':An open door",
254     "(:Soft armor",
255     "):A shield",
256     "*:A vein with treasure or a ball monster",
257     "+:A closed door",
258     ",:Food (or mushroom patch)",
259     "-:A wand (or rod)",
260     ".:Floor",
261     "/:A polearm (Axe/Pike/etc)",
262     "0:Entrance to the Museum",
263     "1:Entrance to the General Store",
264     "2:Entrance to the Armoury",
265     "3:Entrance to the Weaponsmith's Shop",
266     "4:Entrance to the Temple",
267     "5:Entrance to the Alchemy Shop",
268     "6:Entrance to the Magic Shop",
269     "7:Entrance to the Black Market",
270     "8:Entrance to your home",
271     "9:Entrance to the Bookstore",
272     "::Rubble",
273     ";:A rune of protection / an explosive rune",
274     "<:An up staircase",
275     "=:A ring",
276     ">:A down staircase",
277     "?:A scroll",
278     "@:You",
279     "A:Angel",
280     "B:Bird",
281     "C:Canine",
282     "D:Ancient Dragon/Wyrm",
283     "E:Elemental",
284     "F:Dragon Fly",
285     "G:Ghost",
286     "H:Hybrid",
287     "I:Insect",
288     "J:Snake",
289     "K:Killer Beetle",
290     "L:Lich",
291     "M:Multi-Headed Reptile",
292     "N:Mystery Living",
293     "O:Ogre",
294     "P:Giant Humanoid",
295     "Q:Quylthulg (Pulsing Flesh Mound)",
296     "R:Reptile/Amphibian",
297     "S:Spider/Scorpion/Tick",
298     "T:Troll",
299     "U:Major Demon",
300     "V:Vampire",
301     "W:Wight/Wraith/etc",
302     "X:Xorn/Xaren/etc",
303     "Y:Yeti",
304     "Z:Zephyr Hound",
305     "[:Hard armor",
306     "\\:A hafted weapon (mace/whip/etc)",
307     "]:Misc. armor",
308     "^:A trap",
309     "_:A staff",
310     "`:A figurine or statue",
311     "a:Ant",
312     "b:Bat",
313     "c:Centipede",
314     "d:Dragon",
315     "e:Floating Eye",
316     "f:Feline",
317     "g:Golem",
318     "h:Hobbit/Elf/Dwarf",
319     "i:Icky Thing",
320     "j:Jelly",
321     "k:Kobold",
322     "l:Aquatic monster",
323     "m:Mold",
324     "n:Naga",
325     "o:Orc",
326     "p:Person/Human",
327     "q:Quadruped",
328     "r:Rodent",
329     "s:Skeleton",
330     "t:Townsperson",
331     "u:Minor Demon",
332     "v:Vortex",
333     "w:Worm/Worm-Mass",
334     /* "x:unused", */
335     "y:Yeek",
336     "z:Zombie/Mummy",
337     "{:A missile (arrow/bolt/shot)",
338     "|:An edged weapon (sword/dagger/etc)",
339     "}:A launcher (bow/crossbow/sling)",
340     "~:Fluid terrain (or miscellaneous item)",
341 #endif
342
343     nullptr
344 };
345
346 /*
347  * The array of window pointers
348  */
349 std::array<term_type *, 8> angband_terms;
350
351 /*!
352  * スクリーン表示色キャラクタ /
353  * Encode the screen colors
354  */
355 static const concptr color_char = "dwsorgbuDWvyRGBU";
356
357 /*
358  * Specify attr/char pairs for visual special effects
359  * Be sure to use "index & 0x7F" to avoid illegal access
360  */
361 TERM_COLOR misc_to_attr[256];
362 char misc_to_char[256];
363
364 /*
365  * Specify attr/char pairs for inventory items (by tval)
366  * Be sure to use "index & 0x7F" to avoid illegal access
367  */
368 TERM_COLOR tval_to_attr[128];
369
370 /*
371  * Default spell color table
372  */
373 std::map<AttributeType, std::string> gf_colors;
374
375 /*!
376  * @brief 万色表現用にランダムな色を選択する関数 /
377  * Get a legal "multi-hued" color for drawing "spells"
378  * @param max 色IDの最大値
379  * @return 選択した色ID
380  */
381 static TERM_COLOR mh_attr(int max)
382 {
383     constexpr static auto colors = {
384         TERM_RED,
385         TERM_GREEN,
386         TERM_BLUE,
387         TERM_YELLOW,
388         TERM_ORANGE,
389         TERM_VIOLET,
390         TERM_L_RED,
391         TERM_L_GREEN,
392         TERM_L_BLUE,
393         TERM_UMBER,
394         TERM_L_UMBER,
395         TERM_SLATE,
396         TERM_WHITE,
397         TERM_L_WHITE,
398         TERM_L_DARK,
399     };
400
401     std::span<const term_color_type> candidates(colors.begin(), max);
402     return rand_choice(candidates);
403 }
404
405 /*!
406  * @brief 魔法属性に応じたエフェクトの色を返す /
407  * Return a color to use for the bolt/ball spells
408  * @param type 魔法属性
409  * @return 対応する色ID
410  */
411 static TERM_COLOR spell_color(AttributeType type)
412 {
413     /* Check if A.B.'s new graphics should be used (rr9) */
414     if (streq(ANGBAND_GRAF, "new") || streq(ANGBAND_GRAF, "ne2")) {
415         /* Analyze */
416         switch (type) {
417         case AttributeType::PSY_SPEAR:
418             return 0x06;
419         case AttributeType::MISSILE:
420             return 0x0F;
421         case AttributeType::ACID:
422             return 0x04;
423         case AttributeType::ELEC:
424             return 0x02;
425         case AttributeType::FIRE:
426             return 0x00;
427         case AttributeType::COLD:
428             return 0x01;
429         case AttributeType::POIS:
430             return 0x03;
431         case AttributeType::HOLY_FIRE:
432             return 0x00;
433         case AttributeType::HELL_FIRE:
434             return 0x00;
435         case AttributeType::MANA:
436             return 0x0E;
437             /* by henkma */
438         case AttributeType::SEEKER:
439             return 0x0E;
440         case AttributeType::SUPER_RAY:
441             return 0x0E;
442
443         case AttributeType::DEBUG:
444             return 0x0F;
445         case AttributeType::WATER:
446             return 0x04;
447         case AttributeType::NETHER:
448             return 0x07;
449         case AttributeType::CHAOS:
450             return mh_attr(15);
451         case AttributeType::DISENCHANT:
452             return 0x05;
453         case AttributeType::NEXUS:
454             return 0x0C;
455         case AttributeType::CONFUSION:
456             return mh_attr(4);
457         case AttributeType::SOUND:
458             return 0x09;
459         case AttributeType::SHARDS:
460             return 0x08;
461         case AttributeType::FORCE:
462             return 0x09;
463         case AttributeType::INERTIAL:
464             return 0x09;
465         case AttributeType::GRAVITY:
466             return 0x09;
467         case AttributeType::TIME:
468             return 0x09;
469         case AttributeType::LITE_WEAK:
470             return 0x06;
471         case AttributeType::LITE:
472             return 0x06;
473         case AttributeType::DARK_WEAK:
474             return 0x07;
475         case AttributeType::DARK:
476             return 0x07;
477         case AttributeType::PLASMA:
478             return 0x0B;
479         case AttributeType::METEOR:
480             return 0x00;
481         case AttributeType::ICE:
482             return 0x01;
483         case AttributeType::ROCKET:
484             return 0x0F;
485         case AttributeType::DEATH_RAY:
486             return 0x07;
487         case AttributeType::NUKE:
488             return mh_attr(2);
489         case AttributeType::DISINTEGRATE:
490             return 0x05;
491         case AttributeType::PSI:
492         case AttributeType::PSI_DRAIN:
493         case AttributeType::TELEKINESIS:
494         case AttributeType::DOMINATION:
495         case AttributeType::DRAIN_MANA:
496         case AttributeType::MIND_BLAST:
497         case AttributeType::BRAIN_SMASH:
498             return 0x09;
499         case AttributeType::CAUSE_1:
500         case AttributeType::CAUSE_2:
501         case AttributeType::CAUSE_3:
502         case AttributeType::CAUSE_4:
503             return 0x0E;
504         case AttributeType::HAND_DOOM:
505             return 0x07;
506         case AttributeType::CAPTURE:
507             return 0x0E;
508         case AttributeType::IDENTIFY:
509             return 0x01;
510         case AttributeType::ATTACK:
511             return 0x0F;
512         case AttributeType::PHOTO:
513             return 0x06;
514         default:
515             break;
516         }
517     }
518     /* Normal tiles or ASCII */
519     else {
520         TERM_COLOR a;
521
522         /* Lookup the default colors for this type */
523         const auto &color = gf_colors[type];
524
525         if (color.empty()) {
526             return TERM_WHITE;
527         }
528
529         /* Pick a random color */
530         auto c = rand_choice(color);
531
532         /* Lookup this color */
533         a = angband_strchr(color_char, c) - color_char;
534
535         /* Invalid color (note check for < 0 removed, gave a silly
536          * warning because bytes are always >= 0 -- RG) */
537         if (a > 15) {
538             return TERM_WHITE;
539         }
540
541         /* Use this color */
542         return a;
543     }
544
545     /* Standard "color" */
546     return TERM_WHITE;
547 }
548
549 /*!
550  * @brief 始点から終点にかけた方向毎にボルトのキャラクタを返す /
551  * Find the attr/char pair to use for a spell effect
552  * @param y 始点Y座標
553  * @param x 始点X座標
554  * @param ny 終点Y座標
555  * @param nx 終点X座標
556  * @param typ 魔法の効果属性
557  * @return 方向キャラID
558  * @details
559  * <pre>
560  * It is moving (or has moved) from (x,y) to (nx,ny).
561  * If the distance is not "one", we (may) return "*".
562  * </pre>
563  */
564 std::pair<TERM_COLOR, char> bolt_pict(POSITION y, POSITION x, POSITION ny, POSITION nx, AttributeType typ)
565 {
566     int base;
567
568     byte k;
569
570     TERM_COLOR a;
571
572     /* No motion (*) */
573     if ((ny == y) && (nx == x)) {
574         base = 0x30;
575     }
576
577     /* Vertical (|) */
578     else if (nx == x) {
579         base = 0x40;
580     }
581
582     /* Horizontal (-) */
583     else if (ny == y) {
584         base = 0x50;
585     }
586
587     /* Diagonal (/) */
588     else if ((ny - y) == (x - nx)) {
589         base = 0x60;
590     }
591
592     /* Diagonal (\) */
593     else if ((ny - y) == (nx - x)) {
594         base = 0x70;
595     }
596
597     /* Weird (*) */
598     else {
599         base = 0x30;
600     }
601
602     /* Basic spell color */
603     k = spell_color(typ);
604
605     /* Obtain attr/char */
606     a = misc_to_attr[base + k];
607     auto c = misc_to_char[base + k];
608
609     /* Create pict */
610     return { a, c };
611 }
612
613 /*!
614  * @brief シンボル1文字をカラーIDに変更する /
615  * Convert a "color letter" into an "actual" color
616  * The colors are: dwsorgbuDWvyRGBU, as shown below
617  * @param c シンボル文字
618  * @return カラーID
619  */
620 TERM_COLOR color_char_to_attr(char c)
621 {
622     switch (c) {
623     case 'd':
624         return TERM_DARK;
625     case 'w':
626         return TERM_WHITE;
627     case 's':
628         return TERM_SLATE;
629     case 'o':
630         return TERM_ORANGE;
631     case 'r':
632         return TERM_RED;
633     case 'g':
634         return TERM_GREEN;
635     case 'b':
636         return TERM_BLUE;
637     case 'u':
638         return TERM_UMBER;
639
640     case 'D':
641         return TERM_L_DARK;
642     case 'W':
643         return TERM_L_WHITE;
644     case 'v':
645         return TERM_VIOLET;
646     case 'y':
647         return TERM_YELLOW;
648     case 'R':
649         return TERM_L_RED;
650     case 'G':
651         return TERM_L_GREEN;
652     case 'B':
653         return TERM_L_BLUE;
654     case 'U':
655         return TERM_L_UMBER;
656     }
657
658     return 255;
659 }