OSDN Git Service

[Refactor] #38997 do_cmd_write_nikki() に player_type * 引数を追加.
[hengband/hengband.git] / src / main-win.c
1 /*!
2 * @file main-win.c
3 * @brief Windows版固有実装(メインエントリポイント含む)
4 * @date 2018/03/16
5 * @author Hengband Team
6 * @detail
7 *
8 * <h3>概要</h3>
9 * Windows98かその前後の頃を起点としたAPI実装。
10 * 各種のゲームエンジンは無論、
11 * DirectXといった昨今描画に標準的となったライブラリも用いていない。
12 * タイルの描画処理などについては、現在動作の詳細を検証中。
13 *
14 * <h3>フォーク元の概要</h3>
15 * <p>
16 * Copyright (c) 1997 Ben Harrison, Skirmantas Kligys, and others
17 *
18 * This software may be copied and distributed for educational, research,
19 * and not for profit purposes provided that this copyright and statement
20 * are included in all such copies.
21 * </p>
22 * <p>
23 * This file helps Angband work with Windows computers.
24 *
25 * To use this file, use an appropriate "Makefile" or "Project File",
26 * make sure that "WINDOWS" and/or "WIN32" are defined somewhere, and
27 * make sure to obtain various extra files as described below.
28 *
29 * The official compilation uses the CodeWarrior Pro compiler, which
30 * includes a special project file and precompilable header file.
31 * </p>
32 *
33 * <p>
34 * <del>See also "main-dos.c" and "main-ibm.c".</del>
35 * </p>
36 *
37 * <p>
38 * The "lib/user/pref-win.prf" file contains keymaps, macro definitions,
39 * and/or color redefinitions.
40 * </p>
41 *
42 * <p>
43 * The "lib/user/font-win.prf" contains attr/char mappings for use with the
44 * normal "lib/xtra/font/*.fon" font files.
45 * </p>
46 *
47 * <p>
48 * The "lib/user/graf-win.prf" contains attr/char mappings for use with the
49 * special "lib/xtra/graf/*.bmp" bitmap files, which are activated by a menu
50 * item.
51 * </p>
52 *
53 * <p>
54 * Compiling this file, and using the resulting executable, requires
55 * several extra files not distributed with the standard Angband code.
56 * If "USE_GRAPHICS" is defined, then "readdib.h" and "readdib.c" must
57 * be placed into "src/", and the "8X8.BMP" bitmap file must be placed
58 * into "lib/xtra/graf".  In any case, some "*.fon" files (including
59 * "8X13.FON" if nothing else) must be placed into "lib/xtra/font/".
60 * If "USE_SOUND" is defined, then some special library (for example,
61 * "winmm.lib") may need to be linked in, and desired "*.WAV" sound
62 * files must be placed into "lib/xtra/sound/".  All of these extra
63 * files can be found in the "ext-win" archive.
64 * </p>
65 *
66 * <p>
67 * The "Term_xtra_win_clear()" function should probably do a low-level
68 * clear of the current window, and redraw the borders and other things,
69 * if only for efficiency.  
70 * </p>
71 *
72 * <p>
73 * A simpler method is needed for selecting the "tile size" for windows.
74 * </p>
75 *
76 * <p>
77 * The various "warning" messages assume the existance of the "screen.w"
78 * window, I think, and only a few calls actually check for its existance,
79 * this may be okay since "NULL" means "on top of all windows". (?)  The
80 * user must never be allowed to "hide" the main window, or the "menubar"
81 * will disappear.  
82 * </p>
83 *
84 * <p>
85 * Special "Windows Help Files" can be placed into "lib/xtra/help/" for
86 * use with the "winhelp.exe" program.  These files *may* be available
87 * at the ftp site somewhere, but I have not seen them.  
88 * </p>
89 *
90 * <p>
91 * Initial framework (and most code) by Ben Harrison (benh@phial.com).
92 *
93 * Original code by Skirmantas Kligys (kligys@scf.usc.edu).
94 *
95 * Additional code by Ross E Becker (beckerr@cis.ohio-state.edu),
96 * and Chris R. Martin (crm7479@tam2000.tamu.edu).
97 * </p>
98 */
99
100 #include "angband.h"
101 #include "util.h"
102 #include "inet.h"
103
104 #include "cmd-dump.h"
105 #include "view-mainwindow.h"
106 #include "floor.h"
107 #include "floor-events.h"
108 #include "init.h"
109 #include "files.h"
110 #include "scores.h"
111 #include "quest.h"
112 #include "files.h"
113 #include "core.h"
114 #include "world.h"
115 #include "term.h"
116
117 #ifdef WINDOWS
118 #include <windows.h>
119 #include <direct.h>
120 #include <locale.h>
121 #include "z-term.h"
122 #include "save.h"
123 #include "dungeon.h"
124
125 /*
126  * Extract the "WIN32" flag from the compiler
127  */
128 #if defined(__WIN32__) || defined(__WINNT__) || defined(__NT__)
129 # ifndef WIN32
130 #  define WIN32
131 # endif
132 #endif
133
134 /*
135  * Available graphic modes
136  */
137 #define GRAPHICS_NONE       0
138 #define GRAPHICS_ORIGINAL   1
139 #define GRAPHICS_ADAM_BOLT  2
140 #define GRAPHICS_HENGBAND   3
141
142 /*
143  * Hack -- allow use of "screen saver" mode
144  */
145 #define USE_SAVER
146
147
148 /*
149  * Menu constants -- see "ANGBAND.RC"
150  */
151
152 #define IDM_FILE_NEW                    100
153 #define IDM_FILE_OPEN                   101
154 #define IDM_FILE_SAVE                   110
155 #define IDM_FILE_SCORE                  120
156 #define IDM_FILE_MOVIE                  121
157 #define IDM_FILE_EXIT                   130
158
159 #define IDM_WINDOW_VIS_0                200
160 #define IDM_WINDOW_VIS_1                201
161 #define IDM_WINDOW_VIS_2                202
162 #define IDM_WINDOW_VIS_3                203
163 #define IDM_WINDOW_VIS_4                204
164 #define IDM_WINDOW_VIS_5                205
165 #define IDM_WINDOW_VIS_6                206
166 #define IDM_WINDOW_VIS_7                207
167
168 #define IDM_WINDOW_FONT_0               210
169 #define IDM_WINDOW_FONT_1               211
170 #define IDM_WINDOW_FONT_2               212
171 #define IDM_WINDOW_FONT_3               213
172 #define IDM_WINDOW_FONT_4               214
173 #define IDM_WINDOW_FONT_5               215
174 #define IDM_WINDOW_FONT_6               216
175 #define IDM_WINDOW_FONT_7               217
176
177 #define IDM_WINDOW_POS_0                220
178 #define IDM_WINDOW_POS_1                221
179 #define IDM_WINDOW_POS_2                222
180 #define IDM_WINDOW_POS_3                223
181 #define IDM_WINDOW_POS_4                224
182 #define IDM_WINDOW_POS_5                225
183 #define IDM_WINDOW_POS_6                226
184 #define IDM_WINDOW_POS_7                227
185
186 #define IDM_WINDOW_BIZ_0                230
187 #define IDM_WINDOW_BIZ_1                231
188 #define IDM_WINDOW_BIZ_2                232
189 #define IDM_WINDOW_BIZ_3                233
190 #define IDM_WINDOW_BIZ_4                234
191 #define IDM_WINDOW_BIZ_5                235
192 #define IDM_WINDOW_BIZ_6                236
193 #define IDM_WINDOW_BIZ_7                237
194
195 #define IDM_WINDOW_I_WID_0              240
196 #define IDM_WINDOW_I_WID_1              241
197 #define IDM_WINDOW_I_WID_2              242
198 #define IDM_WINDOW_I_WID_3              243
199 #define IDM_WINDOW_I_WID_4              244
200 #define IDM_WINDOW_I_WID_5              245
201 #define IDM_WINDOW_I_WID_6              246
202 #define IDM_WINDOW_I_WID_7              247
203
204 #define IDM_WINDOW_D_WID_0              250
205 #define IDM_WINDOW_D_WID_1              251
206 #define IDM_WINDOW_D_WID_2              252
207 #define IDM_WINDOW_D_WID_3              253
208 #define IDM_WINDOW_D_WID_4              254
209 #define IDM_WINDOW_D_WID_5              255
210 #define IDM_WINDOW_D_WID_6              256
211 #define IDM_WINDOW_D_WID_7              257
212
213 #define IDM_WINDOW_I_HGT_0              260
214 #define IDM_WINDOW_I_HGT_1              261
215 #define IDM_WINDOW_I_HGT_2              262
216 #define IDM_WINDOW_I_HGT_3              263
217 #define IDM_WINDOW_I_HGT_4              264
218 #define IDM_WINDOW_I_HGT_5              265
219 #define IDM_WINDOW_I_HGT_6              266
220 #define IDM_WINDOW_I_HGT_7              267
221
222 #define IDM_WINDOW_D_HGT_0              270
223 #define IDM_WINDOW_D_HGT_1              271
224 #define IDM_WINDOW_D_HGT_2              272
225 #define IDM_WINDOW_D_HGT_3              273
226 #define IDM_WINDOW_D_HGT_4              274
227 #define IDM_WINDOW_D_HGT_5              275
228 #define IDM_WINDOW_D_HGT_6              276
229 #define IDM_WINDOW_D_HGT_7              277
230
231 #define IDM_OPTIONS_NO_GRAPHICS   400
232 #define IDM_OPTIONS_OLD_GRAPHICS  401
233 #define IDM_OPTIONS_NEW_GRAPHICS  402
234 #define IDM_OPTIONS_NEW2_GRAPHICS 403
235 #define IDM_OPTIONS_BIGTILE               409
236 #define IDM_OPTIONS_SOUND                 410
237 #define IDM_OPTIONS_MUSIC                 411
238 #define IDM_OPTIONS_SAVER                 420
239 #define IDM_OPTIONS_MAP                   430
240 #define IDM_OPTIONS_BG                    440
241 #define IDM_OPTIONS_OPEN_BG               441
242
243 #define IDM_DUMP_SCREEN_HTML    450
244
245 #define IDM_HELP_CONTENTS       901
246
247 /*
248  * Exclude parts of WINDOWS.H that are not needed
249  */
250 #define NOCOMM            /* Comm driver APIs and definitions */
251 #define NOLOGERROR        /* LogError() and related definitions */
252 #define NOPROFILER        /* Profiler APIs */
253 #define NOLFILEIO         /* _l* file I/O routines */
254 #define NOOPENFILE        /* OpenFile and related definitions */
255 #define NORESOURCE        /* Resource management */
256 #define NOATOM            /* Atom management */
257 #define NOLANGUAGE        /* Character test routines */
258 #define NOLSTRING         /* lstr* string management routines */
259 #define NODBCS            /* Double-byte character set routines */
260 #define NOKEYBOARDINFO    /* Keyboard driver routines */
261 #define NOCOLOR           /* COLOR_* color values */
262 #define NODRAWTEXT        /* DrawText() and related definitions */
263 #define NOSCALABLEFONT    /* Truetype scalable font support */
264 #define NOMETAFILE        /* Metafile support */
265 #define NOSYSTEMPARAMSINFO /* SystemParametersInfo() and SPI_* definitions */
266 #define NODEFERWINDOWPOS  /* DeferWindowPos and related definitions */
267 #define NOKEYSTATES       /* MK_* message key state flags */
268 #define NOWH              /* SetWindowsHook and related WH_* definitions */
269 #define NOCLIPBOARD       /* Clipboard APIs and definitions */
270 #define NOICONS           /* IDI_* icon IDs */
271 #define NOMDI             /* MDI support */
272 #define NOHELP            /* Help support */
273
274 /* Not defined since it breaks Borland C++ 5.5 */
275 /* #define NOCTLMGR */    /* Control management and controls */
276
277 /*
278  * Exclude parts of WINDOWS.H that are not needed (Win32)
279  */
280 #define WIN32_LEAN_AND_MEAN
281 #define NONLS             /* All NLS defines and routines */
282 #define NOSERVICE         /* All Service Controller routines, SERVICE_ equates, etc. */
283 #define NOKANJI           /* Kanji support stuff. */
284 #define NOMCX             /* Modem Configuration Extensions */
285
286 /*
287  * Include the "windows" support file
288  */
289 #include <windows.h>
290
291 /*
292  * Exclude parts of MMSYSTEM.H that are not needed
293  */
294 #define MMNODRV          /* Installable driver support */
295 #define MMNOWAVE         /* Waveform support */
296 #define MMNOMIDI         /* MIDI support */
297 #define MMNOAUX          /* Auxiliary audio support */
298 #define MMNOTIMER        /* Timer support */
299 #define MMNOJOY          /* Joystick support */
300 #define MMNOMCI          /* MCI support */
301 #define MMNOMMIO         /* Multimedia file I/O support */
302 #define MMNOMMSYSTEM     /* General MMSYSTEM functions */
303
304
305  /*
306   * Standard sound names
307   */
308 const concptr angband_sound_name[SOUND_MAX] =
309 {
310         "dummy",
311         "hit",
312         "miss",
313         "flee",
314         "drop",
315         "kill",
316         "level",
317         "death",
318         "study",
319         "teleport",
320         "shoot",
321         "quaff",
322         "zap",
323         "walk",
324         "tpother",
325         "hitwall",
326         "eat",
327         "store1",
328         "store2",
329         "store3",
330         "store4",
331         "dig",
332         "opendoor",
333         "shutdoor",
334         "tplevel",
335         "scroll",
336         "buy",
337         "sell",
338         "warn",
339         "rocket",
340         "n_kill",
341         "u_kill",
342         "quest",
343         "heal",
344         "x_heal",
345         "bite",
346         "claw",
347         "m_spell",
348         "summon",
349         "breath",
350         "ball",
351         "m_heal",
352         "atkspell",
353         "evil",
354         "touch",
355         "sting",
356         "crush",
357         "slime",
358         "wail",
359         "winner",
360         "fire",
361         "acid",
362         "elec",
363         "cold",
364         "illegal",
365         "fail",
366         "wakeup",
367         "invuln",
368         "fall",
369         "pain",
370         "destitem",
371         "moan",
372         "show",
373         "unused",
374         "explode",
375         "glass",
376         "reflect",
377 };
378
379 /*
380  * Standard music names
381  */
382 const concptr angband_music_basic_name[MUSIC_BASIC_MAX] =
383 {
384         "default",
385         "gameover",
386         "exit",
387         "town",
388         "field1",
389         "field2",
390         "field3",
391         "dun_low",
392         "dun_med",
393         "dun_high",
394         "feel1",
395         "feel2",
396         "winner",
397         "build",
398         "wild",
399         "quest",
400         "arena",
401         "battle",
402         "quest_clear",
403         "final_quest_clear",
404         "ambush",
405 };
406
407 /*
408  * Include some more files. Note: the Cygnus Cygwin compiler
409  * doesn't use mmsystem.h instead it includes the winmm library
410  * which performs a similar function.
411  */
412 #include <mmsystem.h>
413 #include <commdlg.h>
414
415 /*
416  * HTML-Help requires htmlhelp.h and htmlhelp.lib from Microsoft's
417  * HTML Workshop < http://msdn.microsoft.com/workshop/author/htmlhelp/ >.
418  */
419 /* #define HTML_HELP */
420
421 #ifdef HTML_HELP
422 #include <htmlhelp.h>
423 #endif /* HTML_HELP */
424
425 /*
426  * Include the support for loading bitmaps
427  */
428 #ifdef USE_GRAPHICS
429 # include "readdib.h"
430 #endif
431
432 /*
433  * Hack -- Fake declarations from "dos.h" 
434  */
435 #ifdef WIN32
436 #define INVALID_FILE_NAME (DWORD)0xFFFFFFFF
437 #else /* WIN32 */
438 #define FA_LABEL    0x08        /* Volume label */
439 #define FA_DIREC    0x10        /* Directory */
440 unsigned _cdecl _dos_getfileattr(concptr , unsigned *);
441 #endif /* WIN32 */
442
443 /*
444  * Silliness in WIN32 drawing routine
445  */
446 #ifdef WIN32
447 # define MoveTo(H,X,Y) MoveToEx(H, X, Y, NULL)
448 #endif /* WIN32 */
449
450 /*
451  * Silliness for Windows 95
452  */
453 #ifndef WS_EX_TOOLWINDOW
454 # define WS_EX_TOOLWINDOW 0
455 #endif
456
457 /*
458  * Foreground color bits (hard-coded by DOS)
459  */
460 #define VID_BLACK       0x00
461 #define VID_BLUE        0x01
462 #define VID_GREEN       0x02
463 #define VID_CYAN        0x03
464 #define VID_RED         0x04
465 #define VID_MAGENTA     0x05
466 #define VID_YELLOW      0x06
467 #define VID_WHITE       0x07
468
469 /*
470  * Bright text (hard-coded by DOS)
471  */
472 #define VID_BRIGHT      0x08
473
474 /*
475  * Background color bits (hard-coded by DOS)
476  */
477 #define VUD_BLACK       0x00
478 #define VUD_BLUE        0x10
479 #define VUD_GREEN       0x20
480 #define VUD_CYAN        0x30
481 #define VUD_RED         0x40
482 #define VUD_MAGENTA     0x50
483 #define VUD_YELLOW      0x60
484 #define VUD_WHITE       0x70
485
486 /*
487  * Blinking text (hard-coded by DOS)
488  */
489 #define VUD_BRIGHT      0x80
490
491
492 /*
493  * Forward declare
494  */
495 typedef struct _term_data term_data;
496
497 /*!
498  * @struct _term_data
499  * @brief ターム情報構造体 / Extra "term" data
500  * @details
501  * <p>
502  * pos_x / pos_y は各タームの左上点座標を指す。
503  * </p>
504  * <p>
505  * tile_wid / tile_hgt は[ウィンドウ]メニューのタイルの幅/高さを~を
506  * 1ドットずつ調整するステータスを指す。
507  * また、フォントを変更すると都度自動調整される。
508  * </p>
509  * <p>
510  * Note the use of "font_want" for the names of the font file requested by
511  * the user, and the use of "font_file" for the currently active font file.
512  *
513  * The "font_file" is uppercased, and takes the form "8X13.FON", while
514  * "font_want" can be in almost any form as long as it could be construed
515  * as attempting to represent the name of a font.
516  * </p>
517  */
518 struct _term_data
519 {
520         term t;
521         concptr s;
522         HWND w;
523         DWORD dwStyle;
524         DWORD dwExStyle;
525
526         uint keys;
527         TERM_LEN rows;  /* int -> uint */
528         TERM_LEN cols;
529
530         uint pos_x; //!< タームの左上X座標
531         uint pos_y; //!< タームの左上Y座標
532         uint size_wid;
533         uint size_hgt;
534         uint size_ow1;
535         uint size_oh1;
536         uint size_ow2;
537         uint size_oh2;
538
539         bool size_hack;
540         bool xtra_hack;
541         bool visible;
542         bool bizarre;
543         concptr font_want;
544         concptr font_file;
545         HFONT font_id;
546         int font_wid;  //!< フォント横幅
547         int font_hgt;  //!< フォント縦幅
548         int tile_wid;  //!< タイル横幅
549         int tile_hgt;  //!< タイル縦幅
550
551         uint map_tile_wid;
552         uint map_tile_hgt;
553
554         bool map_active;
555 #if 1 /* #ifdef JP */
556         LOGFONT lf;
557 #endif
558
559         bool posfix;
560
561 };
562
563 #define MAX_TERM_DATA 8 //!< Maximum number of windows 
564
565 static term_data data[MAX_TERM_DATA]; //!< An array of term_data's
566 static term_data *my_td; //!< Hack -- global "window creation" pointer
567 POINT normsize; //!< Remember normal size of main window when maxmized
568
569 /*
570  * was main window maximized on previous playing
571  */
572 bool win_maximized = FALSE;
573
574 /*
575  * game in progress
576  */
577 bool game_in_progress = FALSE;
578
579 /*
580  * note when "open"/"new" become valid
581  */
582 bool initialized = FALSE;
583
584 /*
585  * screen paletted, i.e. 256 colors
586  */
587 bool paletted = FALSE;
588
589 /*
590  * 16 colors screen, don't use RGB()
591  */
592 bool colors16 = FALSE;
593
594 /*
595  * Saved instance handle
596  */
597 static HINSTANCE hInstance;
598
599 /*
600  * Yellow brush for the cursor
601  */
602 static HBRUSH hbrYellow;
603
604 /*
605  * An icon
606  */
607 static HICON hIcon;
608
609 /*
610  * A palette
611  */
612 static HPALETTE hPal;
613
614 /* bg */
615 static HBITMAP hBG = NULL;
616 static int use_bg = 0; //!< 背景使用フラグ、1なら私用。
617 static char bg_bitmap_file[1024] = "bg.bmp"; //!< 現在の背景ビットマップファイル名。
618
619 #ifdef USE_SAVER
620
621 /*
622  * The screen saver window
623  */
624 static HWND hwndSaver;
625
626 #endif /* USE_SAVER */
627
628
629 #ifdef USE_GRAPHICS
630
631 /*!
632  * 現在使用中のタイルID(0ならば未使用)
633  * Flag set once "graphics" has been initialized
634  */
635 static byte_hack current_graphics_mode = 0;
636
637 /*
638  * The global bitmap
639  */
640 static DIBINIT infGraph;
641
642 /*
643  * The global bitmap mask
644  */
645 static DIBINIT infMask;
646
647 #endif /* USE_GRAPHICS */
648
649
650 #ifdef USE_SOUND
651
652 /*
653  * Flag set once "sound" has been initialized
654  */
655 static bool can_use_sound = FALSE;
656
657 #define SAMPLE_SOUND_MAX 16
658 /*
659  * An array of sound file names
660  */
661 static concptr sound_file[SOUND_MAX][SAMPLE_SOUND_MAX];
662
663 #endif /* USE_SOUND */
664
665
666
667 #ifdef USE_MUSIC
668
669 #define SAMPLE_MUSIC_MAX 16
670 static concptr music_file[MUSIC_BASIC_MAX][SAMPLE_MUSIC_MAX];
671 static concptr dungeon_music_file[1000][SAMPLE_MUSIC_MAX];
672 static concptr town_music_file[1000][SAMPLE_MUSIC_MAX];
673 static concptr quest_music_file[1000][SAMPLE_MUSIC_MAX];
674 static bool can_use_music = FALSE;
675
676 static MCI_OPEN_PARMS mop;
677 static char mci_device_type[256];
678
679 int current_music_type = 0;
680 int current_music_id = 0;
681
682 #endif /* USE_MUSIC */
683
684
685 /*
686  * Full path to ANGBAND.INI
687  */
688 static concptr ini_file = NULL;
689
690 /*
691  * Name of application
692  */
693 static concptr AppName = "ANGBAND";
694
695 /*
696  * Name of sub-window type
697  */
698 static concptr AngList = "AngList";
699
700 /*
701  * Directory names
702  */
703 static concptr ANGBAND_DIR_XTRA_GRAF;
704 static concptr ANGBAND_DIR_XTRA_SOUND;
705 static concptr ANGBAND_DIR_XTRA_MUSIC;
706 static concptr ANGBAND_DIR_XTRA_HELP;
707 #if 0 /* #ifndef JP */
708 static concptr ANGBAND_DIR_XTRA_FONT;
709 #endif
710 #ifdef USE_MUSIC
711 static concptr ANGBAND_DIR_XTRA_MUSIC;
712 #endif
713
714
715 /*
716  * The "complex" color values
717  */
718 static COLORREF win_clr[256];
719
720
721 /*
722  * Flag for macro trigger with dump ASCII
723  */
724 static bool Term_no_press = FALSE;
725
726 /*
727  * Copy and paste
728  */
729 static bool mouse_down = FALSE;
730 static bool paint_rect = FALSE;
731 static TERM_LEN mousex = 0, mousey = 0;
732 static TERM_LEN oldx, oldy;
733
734
735 /*!
736  * @brief The "simple" color values
737  * @details
738  * See "main-ibm.c" for original table information
739  * The entries below are taken from the "color bits" defined above.
740  * Note that many of the choices below suck, but so do crappy monitors.
741  */
742 static BYTE win_pal[256] =
743 {
744         VID_BLACK,                                      /* Dark */
745         VID_WHITE,                                      /* White */
746         VID_CYAN,                                       /* Slate XXX */
747         VID_RED | VID_BRIGHT,           /* Orange XXX */
748         VID_RED,                                        /* Red */
749         VID_GREEN,                                      /* Green */
750         VID_BLUE,                                       /* Blue */
751         VID_YELLOW,                                     /* Umber XXX */
752         VID_BLACK | VID_BRIGHT,         /* Light Dark */
753         VID_CYAN | VID_BRIGHT,          /* Light Slate XXX */
754         VID_MAGENTA,                            /* Violet XXX */
755         VID_YELLOW | VID_BRIGHT,        /* Yellow */
756         VID_MAGENTA | VID_BRIGHT,       /* Light Red XXX */
757         VID_GREEN | VID_BRIGHT,         /* Light Green */
758         VID_BLUE | VID_BRIGHT,          /* Light Blue */
759         VID_YELLOW                                      /* Light Umber XXX */
760 };
761
762
763 /*
764  * Hack -- define which keys are "special"
765  */
766 static bool special_key[256];
767 static bool ignore_key[256];
768
769 #if 1
770 /*
771  * Hack -- initialization list for "special_key"
772  */
773 static byte special_key_list[] = {
774         VK_CLEAR, VK_PAUSE, VK_CAPITAL,
775         VK_KANA, VK_JUNJA, VK_FINAL, VK_KANJI,
776         VK_CONVERT, VK_NONCONVERT, VK_ACCEPT, VK_MODECHANGE,
777         VK_PRIOR, VK_NEXT, VK_END, VK_HOME,
778         VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN,
779         VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT,
780         VK_INSERT, VK_DELETE, VK_HELP, VK_APPS,
781         VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
782         VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
783         VK_NUMPAD8, VK_NUMPAD9, VK_MULTIPLY, VK_ADD,
784         VK_SEPARATOR, VK_SUBTRACT, VK_DECIMAL, VK_DIVIDE,
785         VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6,
786         VK_F7, VK_F8, VK_F9, VK_F10, VK_F11, VK_F12,
787         VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18,
788         VK_F19,VK_F20, VK_F21, VK_F22, VK_F23, VK_F24,
789         VK_NUMLOCK, VK_SCROLL, VK_ATTN, VK_CRSEL,
790         VK_EXSEL, VK_EREOF, VK_PLAY, VK_ZOOM,
791         VK_NONAME, VK_PA1,
792         0       /* End of List */
793 };
794
795 static byte ignore_key_list[] = {
796         VK_ESCAPE, VK_TAB, VK_SPACE,
797         'F', 'W', 'O', /*'H',*/ /* these are menu characters.*/
798         VK_SHIFT, VK_CONTROL, VK_MENU, VK_LWIN, VK_RWIN,
799         VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL,
800         VK_LMENU, VK_RMENU,
801         0       /* End of List */
802 };
803 #else
804 /*
805  * Hack -- initialization list for "special_key"
806  *
807  * We ignore the modifier keys (shift, control, alt, num lock, scroll lock),
808  * and the normal keys (escape, tab, return, letters, numbers, etc), but we
809  * catch the keypad keys (with and without numlock set, including keypad 5),
810  * the function keys (including the "menu" key which maps to F10), and the
811  * "pause" key (between scroll lock and numlock).  We also catch a few odd
812  * keys which I do not recognize, but which are listed among keys which we
813  * do catch, so they should be harmless to catch.
814  */
815 static byte special_key_list[] =
816 {
817         VK_CLEAR,               /* 0x0C (KP<5>) */
818
819         VK_PAUSE,               /* 0x13 (pause) */
820
821         VK_PRIOR,               /* 0x21 (KP<9>) */
822         VK_NEXT,                /* 0x22 (KP<3>) */
823         VK_END,                 /* 0x23 (KP<1>) */
824         VK_HOME,                /* 0x24 (KP<7>) */
825         VK_LEFT,                /* 0x25 (KP<4>) */
826         VK_UP,                  /* 0x26 (KP<8>) */
827         VK_RIGHT,               /* 0x27 (KP<6>) */
828         VK_DOWN,                /* 0x28 (KP<2>) */
829         VK_SELECT,              /* 0x29 (?????) */
830         VK_PRINT,               /* 0x2A (?????) */
831         VK_EXECUTE,             /* 0x2B (?????) */
832         VK_SNAPSHOT,    /* 0x2C (?????) */
833         VK_INSERT,              /* 0x2D (KP<0>) */
834         VK_DELETE,              /* 0x2E (KP<.>) */
835         VK_HELP,                /* 0x2F (?????) */
836 #if 0
837         VK_NUMPAD0,             /* 0x60 (KP<0>) */
838         VK_NUMPAD1,             /* 0x61 (KP<1>) */
839         VK_NUMPAD2,             /* 0x62 (KP<2>) */
840         VK_NUMPAD3,             /* 0x63 (KP<3>) */
841         VK_NUMPAD4,             /* 0x64 (KP<4>) */
842         VK_NUMPAD5,             /* 0x65 (KP<5>) */
843         VK_NUMPAD6,             /* 0x66 (KP<6>) */
844         VK_NUMPAD7,             /* 0x67 (KP<7>) */
845         VK_NUMPAD8,             /* 0x68 (KP<8>) */
846         VK_NUMPAD9,             /* 0x69 (KP<9>) */
847         VK_MULTIPLY,    /* 0x6A (KP<*>) */
848         VK_ADD,                 /* 0x6B (KP<+>) */
849         VK_SEPARATOR,   /* 0x6C (?????) */
850         VK_SUBTRACT,    /* 0x6D (KP<->) */
851         VK_DECIMAL,             /* 0x6E (KP<.>) */
852         VK_DIVIDE,              /* 0x6F (KP</>) */
853 #endif
854         VK_F1,                  /* 0x70 */
855         VK_F2,                  /* 0x71 */
856         VK_F3,                  /* 0x72 */
857         VK_F4,                  /* 0x73 */
858         VK_F5,                  /* 0x74 */
859         VK_F6,                  /* 0x75 */
860         VK_F7,                  /* 0x76 */
861         VK_F8,                  /* 0x77 */
862         VK_F9,                  /* 0x78 */
863         VK_F10,                 /* 0x79 */
864         VK_F11,                 /* 0x7A */
865         VK_F12,                 /* 0x7B */
866         VK_F13,                 /* 0x7C */
867         VK_F14,                 /* 0x7D */
868         VK_F15,                 /* 0x7E */
869         VK_F16,                 /* 0x7F */
870         VK_F17,                 /* 0x80 */
871         VK_F18,                 /* 0x81 */
872         VK_F19,                 /* 0x82 */
873         VK_F20,                 /* 0x83 */
874         VK_F21,                 /* 0x84 */
875         VK_F22,                 /* 0x85 */
876         VK_F23,                 /* 0x86 */
877         VK_F24,                 /* 0x87 */
878         0
879 };
880 #endif
881
882
883 /* Function prototype */
884
885 static bool is_already_running(void);
886
887
888 /* bg */
889 static void delete_bg(void)
890 {
891         if (hBG != NULL)
892         {
893                 DeleteObject(hBG);
894                 hBG = NULL;
895         }
896 }
897
898 static int init_bg(void)
899 {
900         char * bmfile = bg_bitmap_file;
901
902         delete_bg();
903         if (use_bg == 0) return 0;
904
905         hBG = LoadImage(NULL, bmfile,  IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
906         if (!hBG) {
907                 plog_fmt(_("壁紙用ビットマップ '%s' を読み込めません。", "Can't load the bitmap file '%s'."), bmfile);
908                 use_bg = 0;
909                 return 0;
910         }
911         use_bg = 1;
912         return 1;
913 }
914
915 static void DrawBG(HDC hdc, RECT *r)
916 {
917         HDC hdcSrc;
918         HBITMAP hOld;
919         BITMAP bm;
920         int x = r->left, y = r->top;
921         int nx, ny, sx, sy, swid, shgt, cwid, chgt;
922         
923         if (!use_bg || !hBG)
924                 return;
925
926         nx = x; ny = y;
927         GetObject(hBG, sizeof(bm), &bm);
928         swid = bm.bmWidth; shgt = bm.bmHeight;
929
930         hdcSrc = CreateCompatibleDC(hdc);
931         hOld = SelectObject(hdcSrc, hBG);
932
933         do {
934                 sx = nx % swid;
935                 cwid = MIN(swid - sx, r->right - nx);
936                 do {
937                         sy = ny % shgt;
938                         chgt = MIN(shgt - sy, r->bottom - ny);
939                                 BitBlt(hdc, nx, ny, cwid, chgt, hdcSrc, sx, sy, SRCCOPY);
940                         ny += chgt;
941                 } while (ny < r->bottom);
942                 ny = y;
943                 nx += cwid;
944         } while (nx < r->right);
945         
946         SelectObject(hdcSrc, hOld);
947         DeleteDC(hdcSrc);
948 }
949
950 #if 0
951 /*
952  * Hack -- given a pathname, point at the filename
953  */
954 static concptr extract_file_name(concptr s)
955 {
956         concptr p;
957
958         /* Start at the end */
959         p = s + strlen(s) - 1;
960
961         /* Back up to divider */
962         while ((p >= s) && (*p != ':') && (*p != '\\')) p--;
963
964         /* Return file name */
965         return (p+1);
966 }
967 #endif
968
969
970 /*
971  * Hack -- given a simple filename, extract the "font size" info
972  *
973  * Return a pointer to a static buffer holding the capitalized base name.
974  */
975 #if 0 /* #ifndef JP */
976 static char *analyze_font(char *path, int *wp, int *hp)
977 {
978         int wid, hgt;
979
980         char *s, *p;
981
982         /* Start at the end */
983         p = path + strlen(path) - 1;
984
985         /* Back up to divider */
986         while ((p >= path) && (*p != ':') && (*p != '\\')) --p;
987
988         /* Advance to file name */
989         ++p;
990
991         /* Capitalize */
992         for (s = p; *s; ++s)
993         {
994                 /* Capitalize (be paranoid) */
995                 if (islower(*s)) *s = toupper(*s);
996         }
997
998         /* Find first 'X' */
999         s = my_strchr(p, 'X');
1000
1001         /* Extract font width */
1002         wid = atoi(p);
1003
1004         /* Extract height */
1005         hgt = s ? atoi(s+1) : 0;
1006
1007         /* Save results */
1008         (*wp) = wid;
1009         (*hp) = hgt;
1010         return (p);
1011 }
1012 #endif
1013
1014
1015 /*
1016  * Check for existance of a file
1017  */
1018 static bool check_file(concptr s)
1019 {
1020         char path[1024];
1021
1022 #ifdef WIN32
1023
1024         DWORD attrib;
1025
1026 #else /* WIN32 */
1027
1028         unsigned int attrib;
1029
1030 #endif /* WIN32 */
1031
1032         /* Copy it */
1033         strcpy(path, s);
1034
1035 #ifdef WIN32
1036
1037         /* Examine */
1038         attrib = GetFileAttributes(path);
1039
1040         /* Require valid filename */
1041         if (attrib == INVALID_FILE_NAME) return (FALSE);
1042
1043         /* Prohibit directory */
1044         if (attrib & FILE_ATTRIBUTE_DIRECTORY) return (FALSE);
1045
1046 #else /* WIN32 */
1047
1048         /* Examine and verify */
1049         if (_dos_getfileattr(path, &attrib)) return (FALSE);
1050
1051         /* Prohibit something */
1052         if (attrib & FA_LABEL) return (FALSE);
1053
1054         /* Prohibit directory */
1055         if (attrib & FA_DIREC) return (FALSE);
1056
1057 #endif /* WIN32 */
1058
1059         /* Success */
1060         return (TRUE);
1061 }
1062
1063
1064 /*
1065  * Check for existance of a directory
1066  */
1067 static bool check_dir(concptr s)
1068 {
1069         int i;
1070
1071         char path[1024];
1072
1073 #ifdef WIN32
1074
1075         DWORD attrib;
1076
1077 #else /* WIN32 */
1078
1079         unsigned int attrib;
1080
1081 #endif /* WIN32 */
1082
1083         /* Copy it */
1084         strcpy(path, s);
1085
1086         /* Check length */
1087         i = strlen(path);
1088
1089         /* Remove trailing backslash */
1090         if (i && (path[i-1] == '\\')) path[--i] = '\0';
1091
1092 #ifdef WIN32
1093
1094         /* Examine */
1095         attrib = GetFileAttributes(path);
1096
1097         /* Require valid filename */
1098         if (attrib == INVALID_FILE_NAME) return (FALSE);
1099
1100         /* Require directory */
1101         if (!(attrib & FILE_ATTRIBUTE_DIRECTORY)) return (FALSE);
1102
1103 #else /* WIN32 */
1104
1105         /* Examine and verify */
1106         if (_dos_getfileattr(path, &attrib)) return (FALSE);
1107
1108         /* Prohibit something */
1109         if (attrib & FA_LABEL) return (FALSE);
1110
1111         /* Require directory */
1112         if (!(attrib & FA_DIREC)) return (FALSE);
1113
1114 #endif /* WIN32 */
1115
1116         /* Success */
1117         return (TRUE);
1118 }
1119
1120
1121 /*
1122  * Validate a file
1123  */
1124 static void validate_file(concptr s)
1125 {
1126         /* Verify or fail */
1127         if (!check_file(s))
1128         {
1129                 quit_fmt(_("必要なファイル[%s]が見あたりません。", "Cannot find required file:\n%s"), s);
1130         }
1131 }
1132
1133
1134 /*
1135  * Validate a directory
1136  */
1137 static void validate_dir(concptr s, bool vital)
1138 {
1139         /* Verify or fail */
1140         if (!check_dir(s))
1141         {
1142                 /* This directory contains needed data */
1143                 if (vital)
1144                 {
1145                         quit_fmt(_("必要なディレクトリ[%s]が見あたりません。", "Cannot find required directory:\n%s"), s);
1146                 }
1147                 /* Attempt to create this directory */
1148                 else if (mkdir(s))
1149                 {
1150                         quit_fmt("Unable to create directory:\n%s", s);
1151                 }
1152         }
1153 }
1154
1155
1156 /*!
1157  * @brief (Windows版固有実装)Get the "size" for a window
1158  */
1159 static void term_getsize(term_data *td)
1160 {
1161         RECT rc;
1162         TERM_LEN wid, hgt;
1163         if (td->cols < 1) td->cols = 1;
1164         if (td->rows < 1) td->rows = 1;
1165
1166         /* Window sizes */
1167         wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
1168         hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
1169
1170         /* Fake window size */
1171         rc.left = 0;
1172         rc.right = rc.left + wid;
1173         rc.top = 0;
1174         rc.bottom = rc.top + hgt;
1175
1176         /* rc.right += 1; */
1177         /* rc.bottom += 1; */
1178
1179         /* Adjust */
1180         AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
1181
1182         /* Total size */
1183         td->size_wid = rc.right - rc.left;
1184         td->size_hgt = rc.bottom - rc.top;
1185
1186         /* See CreateWindowEx */
1187         if (!td->w) return;
1188
1189         /* Extract actual location */
1190         GetWindowRect(td->w, &rc);
1191
1192         /* Save the location */
1193         td->pos_x = rc.left;
1194         td->pos_y = rc.top;
1195 }
1196
1197
1198 /*
1199  * Write the "prefs" for a single term
1200  */
1201 static void save_prefs_aux(int i)
1202 {
1203         term_data *td = &data[i];
1204         GAME_TEXT sec_name[128];
1205         char buf[1024];
1206
1207         RECT rc;
1208         WINDOWPLACEMENT lpwndpl;
1209         if (!td->w) return;
1210
1211         /* Make section name */
1212         sprintf(sec_name, "Term-%d", i);
1213
1214         /* Visible */
1215         if (i > 0)
1216         {
1217                 strcpy(buf, td->visible ? "1" : "0");
1218                 WritePrivateProfileString(sec_name, "Visible", buf, ini_file);
1219         }
1220
1221         /* Font */
1222 #ifdef JP
1223         strcpy(buf, td->lf.lfFaceName[0]!='\0' ? td->lf.lfFaceName : "MS ゴシック");
1224 #else
1225 #if 0
1226         strcpy(buf, td->font_file ? td->font_file : "8X13.FON");
1227 #else
1228         strcpy(buf, td->lf.lfFaceName[0]!='\0' ? td->lf.lfFaceName : "Courier");
1229 #endif
1230 #endif
1231
1232         WritePrivateProfileString(sec_name, "Font", buf, ini_file);
1233
1234 #if 1 /* #ifdef JP */
1235         wsprintf(buf, "%d", td->lf.lfWidth);
1236         WritePrivateProfileString(sec_name, "FontWid", buf, ini_file);
1237         wsprintf(buf, "%d", td->lf.lfHeight);
1238         WritePrivateProfileString(sec_name, "FontHgt", buf, ini_file);
1239         wsprintf(buf, "%d", td->lf.lfWeight);
1240         WritePrivateProfileString(sec_name, "FontWgt", buf, ini_file);
1241 #endif
1242         /* Bizarre */
1243         strcpy(buf, td->bizarre ? "1" : "0");
1244         WritePrivateProfileString(sec_name, "Bizarre", buf, ini_file);
1245
1246         /* Tile size (x) */
1247         wsprintf(buf, "%d", td->tile_wid);
1248         WritePrivateProfileString(sec_name, "TileWid", buf, ini_file);
1249
1250         /* Tile size (y) */
1251         wsprintf(buf, "%d", td->tile_hgt);
1252         WritePrivateProfileString(sec_name, "TileHgt", buf, ini_file);
1253
1254         /* Get window placement and dimensions */
1255         lpwndpl.length = sizeof(WINDOWPLACEMENT);
1256         GetWindowPlacement(td->w, &lpwndpl);
1257
1258         /* Acquire position in *normal* mode (not minimized) */
1259         rc = lpwndpl.rcNormalPosition;
1260
1261         /* Window size (x) */
1262         if (i == 0) wsprintf(buf, "%d", normsize.x);
1263         else wsprintf(buf, "%d", td->cols);
1264         WritePrivateProfileString(sec_name, "NumCols", buf, ini_file);
1265
1266         /* Window size (y) */
1267         if (i == 0) wsprintf(buf, "%d", normsize.y);
1268         else wsprintf(buf, "%d", td->rows);
1269         WritePrivateProfileString(sec_name, "NumRows", buf, ini_file);
1270
1271         /* Maxmized (only main window) */
1272         if (i == 0)
1273         {
1274                 strcpy(buf, IsZoomed(td->w) ? "1" : "0");
1275                 WritePrivateProfileString(sec_name, "Maximized", buf, ini_file);
1276         }
1277
1278         /* Acquire position */
1279         GetWindowRect(td->w, &rc);
1280
1281         /* Window position (x) */
1282         wsprintf(buf, "%d", rc.left);
1283         WritePrivateProfileString(sec_name, "PositionX", buf, ini_file);
1284
1285         /* Window position (y) */
1286         wsprintf(buf, "%d", rc.top);
1287         WritePrivateProfileString(sec_name, "PositionY", buf, ini_file);
1288
1289         /* Window Z position */
1290         if (i > 0)
1291         {
1292                 strcpy(buf, td->posfix ? "1" : "0");
1293                 WritePrivateProfileString(sec_name, "PositionFix", buf, ini_file);
1294         }
1295 }
1296
1297
1298 /*
1299  * Write the "prefs"
1300  * We assume that the windows have all been initialized
1301  */
1302 static void save_prefs(void)
1303 {
1304         int i;
1305
1306         char buf[128];
1307
1308         /* Save the "arg_graphics" flag */
1309         sprintf(buf, "%d", arg_graphics);
1310         WritePrivateProfileString("Angband", "Graphics", buf, ini_file);
1311
1312         /* Save the "arg_bigtile" flag */
1313         strcpy(buf, arg_bigtile ? "1" : "0");
1314         WritePrivateProfileString("Angband", "Bigtile", buf, ini_file);
1315
1316         /* Save the "arg_sound" flag */
1317         strcpy(buf, arg_sound ? "1" : "0");
1318         WritePrivateProfileString("Angband", "Sound", buf, ini_file);
1319
1320         /* Save the "arg_sound" flag */
1321         strcpy(buf, arg_music ? "1" : "0");
1322         WritePrivateProfileString("Angband", "Music", buf, ini_file);
1323
1324         /* bg */
1325         strcpy(buf, use_bg ? "1" : "0");
1326         WritePrivateProfileString("Angband", "BackGround", buf, ini_file);
1327         WritePrivateProfileString("Angband", "BackGroundBitmap", 
1328                 bg_bitmap_file[0] != '\0' ? bg_bitmap_file : "bg.bmp", ini_file);
1329
1330         /* Save window prefs */
1331         for (i = 0; i < MAX_TERM_DATA; ++i)
1332         {
1333                 save_prefs_aux(i);
1334         }
1335 }
1336
1337
1338 /*
1339  * Load the "prefs" for a single term
1340  */
1341 static void load_prefs_aux(int i)
1342 {
1343         term_data *td = &data[i];
1344         GAME_TEXT sec_name[128];
1345         char tmp[1024];
1346
1347         int wid, hgt, posx, posy;
1348         int dispx = GetSystemMetrics( SM_CXVIRTUALSCREEN);
1349         int dispy = GetSystemMetrics( SM_CYVIRTUALSCREEN);
1350         posx=0;
1351         posy=0;
1352         
1353         /* Make section name */
1354         sprintf(sec_name, "Term-%d", i);
1355
1356         /* Make section name */
1357         sprintf(sec_name, "Term-%d", i);
1358
1359         /* Visible */
1360         if (i > 0)
1361         {
1362                 td->visible = (GetPrivateProfileInt(sec_name, "Visible", td->visible, ini_file) != 0);
1363         }
1364
1365         /* Desired font, with default */
1366 #ifdef JP
1367         GetPrivateProfileString(sec_name, "Font", "MS ゴシック", tmp, 127, ini_file);
1368 #else
1369 #if 0
1370         GetPrivateProfileString(sec_name, "Font", "8X13.FON", tmp, 127, ini_file);
1371 #else
1372         GetPrivateProfileString(sec_name, "Font", "Courier", tmp, 127, ini_file);
1373 #endif
1374 #endif
1375
1376
1377         /* Bizarre */
1378         td->bizarre = (GetPrivateProfileInt(sec_name, "Bizarre", td->bizarre, ini_file) != 0);
1379
1380         /* Analyze font, save desired font name */
1381 #if 1 /* #ifdef JP */
1382         td->font_want = string_make(tmp);
1383         hgt = 15; wid = 0;
1384         td->lf.lfWidth  = GetPrivateProfileInt(sec_name, "FontWid", wid, ini_file);
1385         td->lf.lfHeight = GetPrivateProfileInt(sec_name, "FontHgt", hgt, ini_file);
1386         td->lf.lfWeight = GetPrivateProfileInt(sec_name, "FontWgt", 0, ini_file);
1387 #else
1388         td->font_want = string_make(analyze_font(tmp, &wid, &hgt));
1389 #endif
1390
1391
1392         /* Tile size */
1393 #if 1 /* #ifdef JP */
1394         td->tile_wid = GetPrivateProfileInt(sec_name, "TileWid", td->lf.lfWidth, ini_file);
1395         td->tile_hgt = GetPrivateProfileInt(sec_name, "TileHgt", td->lf.lfHeight, ini_file);
1396 #else
1397         td->tile_wid = GetPrivateProfileInt(sec_name, "TileWid", wid, ini_file);
1398         td->tile_hgt = GetPrivateProfileInt(sec_name, "TileHgt", hgt, ini_file);
1399 #endif
1400
1401
1402         /* Window size */
1403         td->cols = GetPrivateProfileInt(sec_name, "NumCols", td->cols, ini_file);
1404         td->rows = GetPrivateProfileInt(sec_name, "NumRows", td->rows, ini_file);
1405         normsize.x = td->cols; normsize.y = td->rows;
1406
1407         /* Window size */
1408         if (i == 0)
1409         {
1410                 win_maximized = (GetPrivateProfileInt(sec_name, "Maximized", win_maximized, ini_file) != 0);
1411         }
1412
1413         /* Window position */
1414         posx = GetPrivateProfileInt(sec_name, "PositionX", posx, ini_file);
1415         posy = GetPrivateProfileInt(sec_name, "PositionY", posy, ini_file);
1416         td->pos_x = MIN(MAX(0, posx), dispx-128);
1417         td->pos_y = MIN(MAX(0, posy), dispy-128);
1418
1419         /* Window Z position */
1420         if (i > 0)
1421         {
1422                 td->posfix = (GetPrivateProfileInt(sec_name, "PositionFix", td->posfix, ini_file) != 0);
1423         }
1424 }
1425
1426
1427 /*
1428  * Load the "prefs"
1429  */
1430 static void load_prefs(void)
1431 {
1432         int i;
1433
1434         /* Extract the "arg_graphics" flag */
1435         arg_graphics = (byte_hack)GetPrivateProfileInt("Angband", "Graphics", GRAPHICS_NONE, ini_file);
1436
1437         /* Extract the "arg_bigtile" flag */
1438         arg_bigtile = (GetPrivateProfileInt("Angband", "Bigtile", FALSE, ini_file) != 0);
1439         use_bigtile = arg_bigtile;
1440
1441         /* Extract the "arg_sound" flag */
1442         arg_sound = (GetPrivateProfileInt("Angband", "Sound", 0, ini_file) != 0);
1443
1444         /* Extract the "arg_sound" flag */
1445         arg_music = (GetPrivateProfileInt("Angband", "Music", 0, ini_file) != 0);
1446
1447         /* bg */
1448         use_bg = GetPrivateProfileInt("Angband", "BackGround", 0, ini_file);
1449         GetPrivateProfileString("Angband", "BackGroundBitmap", "bg.bmp", bg_bitmap_file, 1023, ini_file);
1450
1451         /* Load window prefs */
1452         for (i = 0; i < MAX_TERM_DATA; ++i)
1453         {
1454                 load_prefs_aux(i);
1455         }
1456 }
1457
1458 #if defined(USE_SOUND) || defined(USE_MUSIC)
1459
1460 /*
1461  * - Taken from files.c.
1462  *
1463  * Extract "tokens" from a buffer
1464  *
1465  * This function uses "whitespace" as delimiters, and treats any amount of
1466  * whitespace as a single delimiter.  We will never return any empty tokens.
1467  * When given an empty buffer, or a buffer containing only "whitespace", we
1468  * will return no tokens.  We will never extract more than "num" tokens.
1469  *
1470  * By running a token through the "text_to_ascii()" function, you can allow
1471  * that token to include (encoded) whitespace, using "\s" to encode spaces.
1472  *
1473  * We save pointers to the tokens in "tokens", and return the number found.
1474  */
1475 static s16b tokenize_whitespace(char *buf, s16b num, char **tokens)
1476 {
1477         s16b k = 0;
1478         char *s = buf;
1479
1480         /* Process */
1481         while (k < num)
1482         {
1483                 char *t;
1484
1485                 /* Skip leading whitespace */
1486                 for ( ; *s && iswspace(*s); ++s) /* loop */;
1487
1488                 /* All done */
1489                 if (!*s) break;
1490
1491                 /* Find next whitespace, if any */
1492                 for (t = s; *t && !iswspace(*t); ++t) /* loop */;
1493
1494                 /* Nuke and advance (if necessary) */
1495                 if (*t) *t++ = '\0';
1496
1497                 /* Save the token */
1498                 tokens[k++] = s;
1499
1500                 /* Advance */
1501                 s = t;
1502         }
1503
1504         /* Count */
1505         return (k);
1506 }
1507
1508 #endif /* USE_SOUND || USE_MUSIC */
1509
1510 #ifdef USE_SOUND
1511
1512 static void load_sound_prefs(void)
1513 {
1514         int i, j, num;
1515         char tmp[1024];
1516         char ini_path[1024];
1517         char wav_path[1024];
1518         char *zz[SAMPLE_SOUND_MAX];
1519
1520         /* Access the sound.cfg */
1521
1522         path_build(ini_path, 1024, ANGBAND_DIR_XTRA_SOUND, "sound.cfg");
1523
1524         for (i = 0; i < SOUND_MAX; i++)
1525         {
1526                 GetPrivateProfileString("Sound", angband_sound_name[i], "", tmp, 1024, ini_path);
1527
1528                 num = tokenize_whitespace(tmp, SAMPLE_SOUND_MAX, zz);
1529
1530                 for (j = 0; j < num; j++)
1531                 {
1532                         /* Access the sound */
1533                         path_build(wav_path, 1024, ANGBAND_DIR_XTRA_SOUND, zz[j]);
1534
1535                         /* Save the sound filename, if it exists */
1536                         if (check_file(wav_path))
1537                                 sound_file[i][j] = string_make(zz[j]);
1538                 }
1539         }
1540 }
1541
1542 #endif /* USE_SOUND */
1543
1544 #ifdef USE_MUSIC
1545
1546 static void load_music_prefs(void)
1547 {
1548         int i, j, num;
1549         char tmp[1024];
1550         char ini_path[1024];
1551         char wav_path[1024];
1552         char *zz[SAMPLE_MUSIC_MAX];
1553         char key[80];
1554
1555         /* Access the music.cfg */
1556
1557         path_build(ini_path, 1024, ANGBAND_DIR_XTRA_MUSIC, "music.cfg");
1558
1559         GetPrivateProfileString("Device", "type", "", mci_device_type, 256, ini_path);
1560
1561         for (i = 0; i < MUSIC_BASIC_MAX; i++)
1562         {
1563                 GetPrivateProfileString("Basic", angband_music_basic_name[i], "", tmp, 1024, ini_path);
1564
1565                 num = tokenize_whitespace(tmp, SAMPLE_MUSIC_MAX, zz);
1566
1567                 for (j = 0; j < num; j++)
1568                 {
1569                         /* Access the sound */
1570                         path_build(wav_path, 1024, ANGBAND_DIR_XTRA_MUSIC, zz[j]);
1571
1572                         /* Save the sound filename, if it exists */
1573                         if (check_file(wav_path))
1574                                 music_file[i][j] = string_make(zz[j]);
1575                 }
1576         }
1577
1578         for (i = 0; i < max_d_idx; i++)
1579         {
1580                 sprintf(key, "dungeon%03d", i);
1581                 GetPrivateProfileString("Dungeon", key, "", tmp, 1024, ini_path);
1582
1583                 num = tokenize_whitespace(tmp, SAMPLE_MUSIC_MAX, zz);
1584
1585                 for (j = 0; j < num; j++)
1586                 {
1587                         /* Access the sound */
1588                         path_build(wav_path, 1024, ANGBAND_DIR_XTRA_MUSIC, zz[j]);
1589
1590                         /* Save the sound filename, if it exists */
1591                         if (check_file(wav_path))
1592                                 dungeon_music_file[i][j] = string_make(zz[j]);
1593                 }
1594         }
1595
1596         for (i = 0; i < max_q_idx; i++)
1597         {
1598                 sprintf(key, "quest%03d", i);
1599                 GetPrivateProfileString("Quest", key, "", tmp, 1024, ini_path);
1600
1601                 num = tokenize_whitespace(tmp, SAMPLE_MUSIC_MAX, zz);
1602
1603                 for (j = 0; j < num; j++)
1604                 {
1605                         /* Access the sound */
1606                         path_build(wav_path, 1024, ANGBAND_DIR_XTRA_MUSIC, zz[j]);
1607
1608                         /* Save the sound filename, if it exists */
1609                         if (check_file(wav_path))
1610                                 quest_music_file[i][j] = string_make(zz[j]);
1611                 }
1612         }
1613
1614         for (i = 0; i < 1000; i++) /*!< @todo 町最大数指定 */
1615         {
1616                 sprintf(key, "town%03d", i);
1617                 GetPrivateProfileString("Town", key, "", tmp, 1024, ini_path);
1618
1619                 num = tokenize_whitespace(tmp, SAMPLE_MUSIC_MAX, zz);
1620
1621                 for (j = 0; j < num; j++)
1622                 {
1623                         /* Access the sound */
1624                         path_build(wav_path, 1024, ANGBAND_DIR_XTRA_MUSIC, zz[j]);
1625
1626                         /* Save the sound filename, if it exists */
1627                         if (check_file(wav_path))
1628                                 town_music_file[i][j] = string_make(zz[j]);
1629                 }
1630         }
1631
1632
1633 }
1634
1635 #endif /* USE_MUSIC */
1636
1637 /*
1638  * Create the new global palette based on the bitmap palette
1639  * (if any), and the standard 16 entry palette derived from
1640  * "win_clr[]" which is used for the basic 16 Angband colors.
1641  *
1642  * This function is never called before all windows are ready.
1643  *
1644  * This function returns FALSE if the new palette could not be
1645  * prepared, which should normally be a fatal error.  XXX XXX
1646  *
1647  * Note that only some machines actually use a "palette".
1648  */
1649 static int new_palette(void)
1650 {
1651         HPALETTE hBmPal;
1652         HPALETTE hNewPal;
1653         HDC hdc;
1654         int i, nEntries;
1655         int pLogPalSize;
1656         int lppeSize;
1657         LPLOGPALETTE pLogPal;
1658         LPPALETTEENTRY lppe;
1659
1660         term_data *td;
1661
1662
1663         /* This makes no sense */
1664         if (!paletted) return (TRUE);
1665
1666
1667         /* No bitmap */
1668         lppeSize = 0;
1669         lppe = NULL;
1670         nEntries = 0;
1671
1672 #ifdef USE_GRAPHICS
1673
1674         /* Check the bitmap palette */
1675         hBmPal = infGraph.hPalette;
1676
1677         /* Use the bitmap */
1678         if (hBmPal)
1679         {
1680                 lppeSize = 256 * sizeof(PALETTEENTRY);
1681                 lppe = (LPPALETTEENTRY)ralloc(lppeSize);
1682                 nEntries = GetPaletteEntries(hBmPal, 0, 255, lppe);
1683                 if ((nEntries == 0) || (nEntries > 220))
1684                 {
1685                         /* Warn the user */
1686                         plog(_("画面を16ビットか24ビットカラーモードにして下さい。", "Please switch to high- or true-color mode."));
1687
1688                         /* Cleanup */
1689                         rnfree(lppe, lppeSize);
1690
1691                         /* Fail */
1692                         return (FALSE);
1693                 }
1694         }
1695
1696 #endif /* USE_GRAPHICS */
1697
1698         /* Size of palette */
1699         pLogPalSize = sizeof(LOGPALETTE) + (nEntries + 16) * sizeof(PALETTEENTRY);
1700
1701         /* Allocate palette */
1702         pLogPal = (LPLOGPALETTE)ralloc(pLogPalSize);
1703
1704         /* Version */
1705         pLogPal->palVersion = 0x300;
1706
1707         /* Make room for bitmap and normal data */
1708         pLogPal->palNumEntries = nEntries + 16;
1709
1710         /* Save the bitmap data */
1711         for (i = 0; i < nEntries; i++)
1712         {
1713                 pLogPal->palPalEntry[i] = lppe[i];
1714         }
1715
1716         /* Save the normal data */
1717         for (i = 0; i < 16; i++)
1718         {
1719                 LPPALETTEENTRY p;
1720
1721                 /* Access the entry */
1722                 p = &(pLogPal->palPalEntry[i+nEntries]);
1723
1724                 /* Save the colors */
1725                 p->peRed = GetRValue(win_clr[i]);
1726                 p->peGreen = GetGValue(win_clr[i]);
1727                 p->peBlue = GetBValue(win_clr[i]);
1728
1729                 /* Save the flags */
1730                 p->peFlags = PC_NOCOLLAPSE;
1731         }
1732
1733         /* Free something */
1734         if (lppe) rnfree(lppe, lppeSize);
1735
1736         /* Create a new palette, or fail */
1737         hNewPal = CreatePalette(pLogPal);
1738         if (!hNewPal) quit(_("パレットを作成できません!", "Cannot create palette!"));
1739
1740         /* Free the palette */
1741         rnfree(pLogPal, pLogPalSize);
1742
1743         /* Main window */
1744         td = &data[0];
1745
1746         /* Realize the palette */
1747         hdc = GetDC(td->w);
1748         SelectPalette(hdc, hNewPal, 0);
1749         i = RealizePalette(hdc);
1750         ReleaseDC(td->w, hdc);
1751         if (i == 0) quit(_("パレットをシステムエントリにマップできません!", "Cannot realize palette!"));
1752
1753
1754         /* Sub-windows */
1755         for (i = 1; i < MAX_TERM_DATA; i++)
1756         {
1757                 td = &data[i];
1758
1759                 hdc = GetDC(td->w);
1760                 SelectPalette(hdc, hNewPal, 0);
1761                 ReleaseDC(td->w, hdc);
1762         }
1763
1764         /* Delete old palette */
1765         if (hPal) DeleteObject(hPal);
1766
1767         /* Save new palette */
1768         hPal = hNewPal;
1769
1770         /* Success */
1771         return (TRUE);
1772 }
1773
1774
1775 #ifdef USE_GRAPHICS
1776 /*!
1777  * @brief グラフィクスを初期化する / Initialize graphics
1778  * @details
1779  * <ul>
1780  * <li>メニュー[オプション]>[グラフィクス]が「なし」以外の時に描画処理を初期化する。</li>
1781  * <li>呼び出されるタイミングはロード時、及び同メニューで「なし」以外に変更される毎になる。</li>
1782  * </ul>
1783  */
1784 static bool init_graphics(void)
1785 {
1786         /* Initialize once */
1787         char buf[1024];
1788         BYTE wid, hgt, twid, thgt, ox, oy;
1789         concptr name;
1790
1791         if (arg_graphics == GRAPHICS_ADAM_BOLT)
1792         {
1793                 wid = 16;
1794                 hgt = 16;
1795                 twid = 16;
1796                 thgt = 16;
1797                 ox = 0;
1798                 oy = 0;
1799                 name = "16X16.BMP";
1800
1801                 ANGBAND_GRAF = "new";
1802         }
1803         else if (arg_graphics == GRAPHICS_HENGBAND)
1804         {
1805                 /*! @todo redraw
1806                 wid = 64;
1807                 hgt = 64;
1808                 twid = 32;
1809                 thgt = 32;
1810                 ox = -16;
1811                 oy = -24;
1812                 name = "64X64.BMP";
1813                 */
1814
1815                 wid = 32;
1816                 hgt = 32;
1817                 twid = 32;
1818                 thgt = 32;
1819                 ox = 0;
1820                 oy = 0;
1821                 name = "32X32.BMP";
1822
1823                 ANGBAND_GRAF = "ne2";
1824         }
1825         else
1826         {
1827                 wid = 8;
1828                 hgt = 8;
1829                 twid = 8;
1830                 thgt = 8;
1831                 ox = 0;
1832                 oy = 0;
1833                 name = "8X8.BMP";
1834                 ANGBAND_GRAF = "old";
1835         }
1836
1837         /* Access the bitmap file */
1838         path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, name);
1839
1840         /* Load the bitmap or quit */
1841         if (!ReadDIB(data[0].w, buf, &infGraph))
1842         {
1843                 plog_fmt(_("ビットマップ '%s' を読み込めません。", "Cannot read bitmap file '%s'"), name);
1844                 return (FALSE);
1845         }
1846
1847         /* Save the new sizes */
1848         infGraph.CellWidth = wid;
1849         infGraph.CellHeight = hgt;
1850         infGraph.TileWidth = twid;
1851         infGraph.TileHeight = thgt;
1852         infGraph.OffsetX = ox;
1853         infGraph.OffsetY = oy;
1854
1855         if (arg_graphics == GRAPHICS_ADAM_BOLT)
1856         {
1857                 /* Access the mask file */
1858                 path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, "mask.bmp");
1859
1860                 /* Load the bitmap or quit */
1861                 if (!ReadDIB(data[0].w, buf, &infMask))
1862                 {
1863                         plog_fmt("Cannot read bitmap file '%s'", buf);
1864                         return (FALSE);
1865                 }
1866         }
1867         if (arg_graphics == GRAPHICS_HENGBAND)
1868         {
1869                 /* Access the mask file */
1870                 path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, "mask32.bmp");
1871
1872                 /* Load the bitmap or quit */
1873                 if (!ReadDIB(data[0].w, buf, &infMask))
1874                 {
1875                         plog_fmt("Cannot read bitmap file '%s'", buf);
1876                         return (FALSE);
1877                 }
1878         }
1879
1880         /* Activate a palette */
1881         if (!new_palette())
1882         {
1883                 /* Free bitmap */
1884
1885                 plog(_("パレットを実現できません!", "Cannot activate palette!"));
1886                 return (FALSE);
1887         }
1888
1889         /* Graphics available */
1890         current_graphics_mode = arg_graphics;
1891         return (current_graphics_mode);
1892 }
1893 #endif /* USE_GRAPHICS */
1894
1895
1896 #ifdef USE_MUSIC
1897 /*
1898  * Initialize music
1899  */
1900 static bool init_music(void)
1901 {
1902         /* Initialize once */
1903         if (!can_use_music)
1904         {
1905                 /* Load the prefs */
1906                 load_music_prefs();
1907
1908                 /* Sound available */
1909                 can_use_music = TRUE;
1910         }
1911         return (can_use_music);
1912 }
1913
1914 /*
1915  * Hack -- Stop a music
1916  */
1917 static void stop_music(void)
1918 {
1919         mciSendCommand(mop.wDeviceID, MCI_STOP, 0, 0);
1920         mciSendCommand(mop.wDeviceID, MCI_CLOSE, 0, 0);
1921 }
1922
1923 #endif /* USE_MUSIC */
1924
1925 #ifdef USE_SOUND
1926 /*
1927  * Initialize sound
1928  */
1929 static bool init_sound(void)
1930 {
1931         /* Initialize once */
1932         if (!can_use_sound)
1933         {
1934                 /* Load the prefs */
1935                 load_sound_prefs();
1936
1937                 /* Sound available */
1938                 can_use_sound = TRUE;
1939         }
1940         return (can_use_sound);
1941 }
1942 #endif /* USE_SOUND */
1943
1944
1945 /*
1946  * Resize a window
1947  */
1948 static void term_window_resize(term_data *td)
1949 {
1950         /* Require window */
1951         if (!td->w) return;
1952
1953         /* Resize the window */
1954         SetWindowPos(td->w, 0, 0, 0,
1955                      td->size_wid, td->size_hgt,
1956                      SWP_NOMOVE | SWP_NOZORDER);
1957
1958         /* Redraw later */
1959         InvalidateRect(td->w, NULL, TRUE);
1960 }
1961
1962
1963 /*
1964  * Force the use of a new "font file" for a term_data
1965  *
1966  * This function may be called before the "window" is ready
1967  *
1968  * This function returns zero only if everything succeeds.
1969  *
1970  * Note that the "font name" must be capitalized!!!
1971  */
1972 static errr term_force_font(term_data *td, concptr path)
1973 {
1974         int wid, hgt;
1975
1976 #if 0 /* #ifndef JP */
1977         int i;
1978         char *base;
1979         char buf[1024];
1980 #endif
1981
1982         /* Forget the old font (if needed) */
1983         if (td->font_id) DeleteObject(td->font_id);
1984
1985 #if 1 /* #ifdef JP */
1986         /* Unused */
1987         (void)path;
1988
1989         /* Create the font (using the 'base' of the font file name!) */
1990         td->font_id = CreateFontIndirect(&(td->lf));
1991         wid = td->lf.lfWidth;
1992         hgt = td->lf.lfHeight;
1993         if (!td->font_id) return (1);
1994 #else
1995         /* Forget old font */
1996         if (td->font_file)
1997         {
1998                 bool used = FALSE;
1999
2000                 /* Scan windows */
2001                 for (i = 0; i < MAX_TERM_DATA; i++)
2002                 {
2003                         /* Don't check when closing the application */
2004                         if (!path) break;
2005
2006                         /* Check "screen" */
2007                         if ((td != &data[i]) &&
2008                             (data[i].font_file) &&
2009                             (streq(data[i].font_file, td->font_file)))
2010                         {
2011                                 used = TRUE;
2012                         }
2013                 }
2014
2015                 /* Remove unused font resources */
2016                 if (!used) RemoveFontResource(td->font_file);
2017
2018                 /* Free the old name */
2019                 string_free(td->font_file);
2020
2021                 /* Forget it */
2022                 td->font_file = NULL;
2023         }
2024
2025         /* No path given */
2026         if (!path) return (1);
2027
2028         /* Local copy */
2029         strcpy(buf, path);
2030
2031         /* Analyze font path */
2032         base = analyze_font(buf, &wid, &hgt);
2033
2034         /* Verify suffix */
2035         if (!suffix(base, ".FON")) return (1);
2036
2037         /* Verify file */
2038         if (!check_file(buf)) return (1);
2039
2040         /* Load the new font */
2041         if (!AddFontResource(buf)) return (1);
2042
2043         /* Save new font name */
2044         td->font_file = string_make(base);
2045
2046         /* Remove the "suffix" */
2047         base[strlen(base)-4] = '\0';
2048
2049         /* Create the font (using the 'base' of the font file name!) */
2050         td->font_id = CreateFont(hgt, wid, 0, 0, FW_DONTCARE, 0, 0, 0,
2051                                  ANSI_CHARSET, OUT_DEFAULT_PRECIS,
2052                                  CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
2053                                  FIXED_PITCH | FF_DONTCARE, base);
2054 #endif
2055
2056         /* Hack -- Unknown size */
2057         if (!wid || !hgt)
2058         {
2059                 HDC hdcDesktop;
2060                 HFONT hfOld;
2061                 TEXTMETRIC tm;
2062
2063                 /* all this trouble to get the cell size */
2064                 hdcDesktop = GetDC(HWND_DESKTOP);
2065                 hfOld = SelectObject(hdcDesktop, td->font_id);
2066                 GetTextMetrics(hdcDesktop, &tm);
2067                 SelectObject(hdcDesktop, hfOld);
2068                 ReleaseDC(HWND_DESKTOP, hdcDesktop);
2069
2070                 /* Font size info */
2071                 wid = tm.tmAveCharWidth;
2072                 hgt = tm.tmHeight;
2073         }
2074
2075         /* Save the size info */
2076         td->font_wid = wid;
2077         td->font_hgt = hgt;
2078
2079         /* Success */
2080         return (0);
2081 }
2082
2083
2084
2085 /*
2086  * Allow the user to change the font for this window.
2087  */
2088 static void term_change_font(term_data *td)
2089 {
2090 #if 1 /* #ifdef JP */
2091         CHOOSEFONT cf;
2092
2093         memset(&cf, 0, sizeof(cf));
2094         cf.lStructSize = sizeof(cf);
2095     cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_NOVERTFONTS | CF_INITTOLOGFONTSTRUCT;
2096     cf.lpLogFont = &(td->lf);
2097
2098         if (ChooseFont(&cf))
2099         {
2100                 /* Force the font */
2101                 term_force_font(td, NULL);
2102
2103                 /* Assume not bizarre */
2104                 td->bizarre = TRUE;
2105
2106                 /* Reset the tile info */
2107                 td->tile_wid = td->font_wid;
2108                 td->tile_hgt = td->font_hgt;
2109
2110                 /* Analyze the font */
2111                 term_getsize(td);
2112
2113                 /* Resize the window */
2114                 term_window_resize(td);
2115         }
2116
2117 #else
2118         OPENFILENAME ofn;
2119
2120         char tmp[1024] = "";
2121
2122         /* Extract a default if possible */
2123         if (td->font_file) strcpy(tmp, td->font_file);
2124
2125         /* Ask for a choice */
2126         memset(&ofn, 0, sizeof(ofn));
2127         ofn.lStructSize = sizeof(ofn);
2128         ofn.hwndOwner = data[0].w;
2129         ofn.lpstrFilter = "Angband Font Files (*.fon)\0*.fon\0";
2130         ofn.nFilterIndex = 1;
2131         ofn.lpstrFile = tmp;
2132         ofn.nMaxFile = 128;
2133         ofn.lpstrInitialDir = ANGBAND_DIR_XTRA_FONT;
2134         ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
2135         ofn.lpstrDefExt = "fon";
2136
2137         /* Force choice if legal */
2138         if (GetOpenFileName(&ofn))
2139         {
2140                 /* Force the font */
2141                 if (term_force_font(td, tmp))
2142                 {
2143                         /* Access the standard font file */
2144                         path_build(tmp, sizeof(tmp), ANGBAND_DIR_XTRA_FONT, "8X13.FON");
2145
2146                         /* Force the use of that font */
2147                         (void)term_force_font(td, tmp);
2148                 }
2149
2150                 /* Assume not bizarre */
2151                 td->bizarre = FALSE;
2152
2153                 /* Reset the tile info */
2154                 td->tile_wid = td->font_wid;
2155                 td->tile_hgt = td->font_hgt;
2156
2157                 /* Analyze the font */
2158                 term_getsize(td);
2159
2160                 /* Resize the window */
2161                 term_window_resize(td);
2162         }
2163 #endif
2164
2165 }
2166
2167 /*
2168  * Allow the user to lock this window.
2169  */
2170 static void term_window_pos(term_data *td, HWND hWnd)
2171 {
2172         SetWindowPos(td->w, hWnd, 0, 0, 0, 0,
2173                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
2174 }
2175
2176 static void windows_map(void);
2177
2178 /*
2179  * Hack -- redraw a term_data
2180  */
2181 static void term_data_redraw(term_data *td)
2182 {
2183         if (td->map_active)
2184         {
2185                 /* Redraw the map */
2186                 windows_map();
2187         }
2188         else
2189         {
2190                 /* Activate the term */
2191                 Term_activate(&td->t);
2192
2193                 /* Redraw the contents */
2194                 Term_redraw();
2195
2196                 /* Restore the term */
2197                 Term_activate(term_screen);
2198         }
2199 }
2200
2201
2202 void Term_inversed_area(HWND hWnd, int x, int y, int w, int h)
2203 {
2204         HDC hdc;
2205         HPEN oldPen;
2206         HBRUSH myBrush, oldBrush;
2207
2208         term_data *td = (term_data *)GetWindowLong(hWnd, 0);
2209         int tx = td->size_ow1 + x * td->tile_wid;
2210         int ty = td->size_oh1 + y * td->tile_hgt;
2211         int tw = w * td->tile_wid - 1;
2212         int th = h * td->tile_hgt - 1;
2213
2214         hdc = GetDC(hWnd);
2215         myBrush = CreateSolidBrush(RGB(255, 255, 255));
2216         oldBrush = SelectObject(hdc, myBrush);
2217         oldPen = SelectObject(hdc, GetStockObject(NULL_PEN) );
2218
2219         PatBlt(hdc, tx, ty, tw, th, PATINVERT);
2220
2221         SelectObject(hdc, oldBrush);
2222         SelectObject(hdc, oldPen);
2223 }
2224
2225
2226
2227 /*** Function hooks needed by "Term" ***/
2228
2229
2230 #if 0
2231
2232 /*
2233  * Initialize a new Term
2234  */
2235 static void Term_init_win(term *t)
2236 {
2237         /* XXX Unused */
2238 }
2239
2240
2241 /*
2242  * Nuke an old Term
2243  */
2244 static void Term_nuke_win(term *t)
2245 {
2246         /* XXX Unused */
2247 }
2248
2249 #endif
2250
2251
2252 /*!
2253  * @brief //!< Windows版ユーザ設定項目実装部(実装必須) /Interact with the User
2254  */
2255 static errr Term_user_win(int n)
2256 {
2257         /* Unused */
2258         (void)n;
2259
2260         /* Success */
2261         return (0);
2262 }
2263
2264
2265 /*
2266  * React to global changes
2267  */
2268 static errr Term_xtra_win_react(void)
2269 {
2270         int i;
2271
2272         /* Simple color */
2273         if (colors16)
2274         {
2275                 /* Save the default colors */
2276                 for (i = 0; i < 256; i++)
2277                 {
2278                         /* Simply accept the desired colors */
2279                         win_pal[i] = angband_color_table[i][0];
2280                 }
2281         }
2282
2283         /* Complex color */
2284         else
2285         {
2286                 COLORREF code;
2287
2288                 byte rv, gv, bv;
2289
2290                 bool change = FALSE;
2291
2292                 /* Save the default colors */
2293                 for (i = 0; i < 256; i++)
2294                 {
2295                         /* Extract desired values */
2296                         rv = angband_color_table[i][1];
2297                         gv = angband_color_table[i][2];
2298                         bv = angband_color_table[i][3];
2299
2300                         /* Extract a full color code */
2301                         code = PALETTERGB(rv, gv, bv);
2302
2303                         /* Activate changes */
2304                         if (win_clr[i] != code)
2305                         {
2306                                 /* Note the change */
2307                                 change = TRUE;
2308
2309                                 /* Apply the desired color */
2310                                 win_clr[i] = code;
2311                         }
2312                 }
2313
2314                 /* Activate the palette if needed */
2315                 if (change) (void)new_palette();
2316         }
2317
2318
2319 #ifdef USE_SOUND
2320
2321         /* Handle "arg_sound" */
2322         if (use_sound != arg_sound)
2323         {
2324                 /* Initialize (if needed) */
2325                 if (arg_sound && !init_sound())
2326                 {
2327                         /* Warning */
2328                         plog(_("サウンドを初期化できません!", "Cannot initialize sound!"));
2329
2330                         /* Cannot enable */
2331                         arg_sound = FALSE;
2332                 }
2333
2334                 /* Change setting */
2335                 use_sound = arg_sound;
2336         }
2337
2338 #endif
2339
2340 #ifdef USE_MUSIC
2341
2342         /* Handle "arg_sound" */
2343         if (use_music != arg_music)
2344         {
2345                 /* Initialize (if needed) */
2346                 if (arg_music && !init_music())
2347                 {
2348                         /* Warning */
2349                         plog(_("BGMを初期化できません!", "Cannot initialize BGM!"));
2350                         /* Cannot enable */
2351                         arg_music = FALSE;
2352                 }
2353
2354                 /* Change setting */
2355                 use_music = arg_music;
2356
2357                 if(!arg_music) stop_music();
2358                 else select_floor_music();
2359
2360         }
2361
2362 #endif
2363
2364
2365 #ifdef USE_GRAPHICS
2366
2367         /* Handle "arg_graphics" */
2368         if (use_graphics != arg_graphics)
2369         {
2370                 /* Initialize (if needed) */
2371                 if (arg_graphics && !init_graphics())
2372                 {
2373                         /* Warning */
2374                         plog(_("グラフィックスを初期化できません!", "Cannot initialize graphics!"));
2375
2376                         /* Cannot enable */
2377                         arg_graphics = GRAPHICS_NONE;
2378                 }
2379
2380                 /* Change setting */
2381                 use_graphics = arg_graphics;
2382
2383                 /* Reset visuals */
2384 #ifdef ANGBAND_2_8_1
2385                 reset_visuals();
2386 #else /* ANGBAND_2_8_1 */
2387                 reset_visuals(TRUE);
2388 #endif /* ANGBAND_2_8_1 */
2389         }
2390
2391 #endif /* USE_GRAPHICS */
2392
2393
2394         /* Clean up windows */
2395         for (i = 0; i < MAX_TERM_DATA; i++)
2396         {
2397                 term *old = Term;
2398
2399                 term_data *td = &data[i];
2400
2401                 /* Update resized windows */
2402                 if ((td->cols != td->t.wid) || (td->rows != td->t.hgt))
2403                 {
2404                         /* Activate */
2405                         Term_activate(&td->t);
2406
2407                         /* Hack -- Resize the term */
2408                         Term_resize(td->cols, td->rows);
2409
2410                         /* Redraw the contents */
2411                         Term_redraw();
2412                         Term_activate(old);
2413                 }
2414         }
2415
2416
2417         /* Success */
2418         return (0);
2419 }
2420
2421
2422 /*
2423  * Process at least one event
2424  */
2425 static errr Term_xtra_win_event(int v)
2426 {
2427         MSG msg;
2428
2429         /* Wait for an event */
2430         if (v)
2431         {
2432                 /* Block */
2433                 if (GetMessage(&msg, NULL, 0, 0))
2434                 {
2435                         TranslateMessage(&msg);
2436                         DispatchMessage(&msg);
2437                 }
2438         }
2439
2440         /* Check for an event */
2441         else
2442         {
2443                 /* Check */
2444                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
2445                 {
2446                         TranslateMessage(&msg);
2447                         DispatchMessage(&msg);
2448                 }
2449         }
2450
2451         /* Success */
2452         return 0;
2453 }
2454
2455
2456 /*
2457  * Process all pending events
2458  */
2459 static errr Term_xtra_win_flush(void)
2460 {
2461         MSG msg;
2462
2463         /* Process all pending events */
2464         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
2465         {
2466                 TranslateMessage(&msg);
2467                 DispatchMessage(&msg);
2468         }
2469
2470         /* Success */
2471         return (0);
2472 }
2473
2474
2475 /*
2476  * Hack -- clear the screen
2477  *
2478  * Make this more efficient 
2479  */
2480 static errr Term_xtra_win_clear(void)
2481 {
2482         term_data *td = (term_data*)(Term->data);
2483
2484         HDC hdc;
2485         RECT rc;
2486
2487         /* Rectangle to erase */
2488         rc.left = td->size_ow1;
2489         rc.right = rc.left + td->cols * td->tile_wid;
2490         rc.top = td->size_oh1;
2491         rc.bottom = rc.top + td->rows * td->tile_hgt;
2492
2493         /* Erase it */
2494         hdc = GetDC(td->w);
2495         SetBkColor(hdc, RGB(0, 0, 0));
2496         SelectObject(hdc, td->font_id);
2497         ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
2498
2499         /* bg */
2500         if (use_bg)
2501         {
2502                 rc.left = 0; rc.top = 0;
2503                 DrawBG(hdc, &rc);
2504         }
2505         ReleaseDC(td->w, hdc);
2506
2507         /* Success */
2508         return 0;
2509 }
2510
2511
2512 /*
2513  * Hack -- make a noise
2514  */
2515 static errr Term_xtra_win_noise(void)
2516 {
2517         MessageBeep(MB_ICONASTERISK);
2518         return (0);
2519 }
2520
2521
2522 /*
2523  * Hack -- make a sound
2524  */
2525 static errr Term_xtra_win_sound(int v)
2526 {
2527 #ifdef USE_SOUND
2528         int i;
2529         char buf[1024];
2530 #endif /* USE_SOUND */
2531
2532         /* Sound disabled */
2533         if (!use_sound) return (1);
2534
2535         /* Illegal sound */
2536         if ((v < 0) || (v >= SOUND_MAX)) return (1);
2537
2538 #ifdef USE_SOUND
2539
2540         /* Count the samples */
2541         for (i = 0; i < SAMPLE_SOUND_MAX; i++)
2542         {
2543                 if (!sound_file[v][i])
2544                         break;
2545         }
2546
2547         /* No sample */
2548         if (i == 0) return (1);
2549
2550         /* Build the path */
2551         path_build(buf, 1024, ANGBAND_DIR_XTRA_SOUND, sound_file[v][Rand_external(i)]);
2552
2553 #ifdef WIN32
2554
2555         /* Play the sound, catch errors */
2556         return (PlaySound(buf, 0, SND_FILENAME | SND_ASYNC));
2557
2558 #else /* WIN32 */
2559
2560         /* Play the sound, catch errors */
2561         return (sndPlaySound(buf, SND_ASYNC));
2562
2563 #endif /* WIN32 */
2564
2565 #else /* USE_SOUND */
2566
2567         return (1);
2568
2569 #endif /* USE_SOUND */
2570 }
2571
2572 /*
2573  * Hack -- play a music
2574  */
2575 static errr Term_xtra_win_music(int n, int v)
2576 {
2577 #ifdef USE_MUSIC
2578         int i = 0;
2579         char buf[1024];
2580 #endif /* USE_MUSIC */
2581
2582         /* Sound disabled */
2583         if (n == TERM_XTRA_MUSIC_MUTE)
2584         {
2585                 mciSendCommand(mop.wDeviceID, MCI_STOP, 0, 0);
2586                 mciSendCommand(mop.wDeviceID, MCI_CLOSE, 0, 0);
2587         }
2588
2589         if(!use_music) return (1);
2590
2591         /* Illegal sound */
2592         if(n == TERM_XTRA_MUSIC_BASIC && ((v < 0) || (v >= MUSIC_BASIC_MAX))) return (1);
2593         else if(v < 0 || v >= 1000) return(1); /*!< TODO */
2594
2595 #ifdef USE_MUSIC
2596
2597         switch(n)
2598         {
2599         case TERM_XTRA_MUSIC_BASIC:
2600                 for (i = 0; i < SAMPLE_MUSIC_MAX; i++) if(!music_file[v][i]) break;
2601                 break;
2602         case TERM_XTRA_MUSIC_DUNGEON:
2603                 for (i = 0; i < SAMPLE_MUSIC_MAX; i++) if(!dungeon_music_file[v][i]) break;
2604                 break;
2605         case TERM_XTRA_MUSIC_QUEST:
2606                 for (i = 0; i < SAMPLE_MUSIC_MAX; i++) if(!quest_music_file[v][i]) break;
2607                 break;
2608         case TERM_XTRA_MUSIC_TOWN:
2609                 for (i = 0; i < SAMPLE_MUSIC_MAX; i++) if(!town_music_file[v][i]) break;
2610                 break;
2611         }
2612
2613         /* No sample */
2614         if (i == 0)
2615         {
2616                 return (1);
2617         }
2618
2619         switch(n)
2620         {
2621         case TERM_XTRA_MUSIC_BASIC:
2622                 path_build(buf, 1024, ANGBAND_DIR_XTRA_MUSIC, music_file[v][Rand_external(i)]);
2623                 break;
2624         case TERM_XTRA_MUSIC_DUNGEON:
2625                 path_build(buf, 1024, ANGBAND_DIR_XTRA_MUSIC, dungeon_music_file[v][Rand_external(i)]);
2626                 break;
2627         case TERM_XTRA_MUSIC_QUEST:
2628                 path_build(buf, 1024, ANGBAND_DIR_XTRA_MUSIC, quest_music_file[v][Rand_external(i)]);
2629                 break;
2630         case TERM_XTRA_MUSIC_TOWN:
2631                 path_build(buf, 1024, ANGBAND_DIR_XTRA_MUSIC, town_music_file[v][Rand_external(i)]);
2632                 break;
2633         }
2634
2635         if(current_music_type == n && current_music_id == v)
2636         {
2637                 return (0);
2638         }
2639         current_music_type = n;
2640         current_music_id = v;
2641
2642 #ifdef WIN32
2643
2644         mop.lpstrDeviceType = mci_device_type;  
2645         mop.lpstrElementName = buf;
2646         mciSendCommand(mop.wDeviceID, MCI_STOP, 0, 0);
2647         mciSendCommand(mop.wDeviceID, MCI_CLOSE, 0, 0);
2648         mciSendCommand(mop.wDeviceID, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)&mop);
2649         mciSendCommand(mop.wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, 0);
2650         mciSendCommand(mop.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)&mop);
2651         return (0);
2652
2653 #endif /* WIN32 */
2654
2655 #else /* USE_MUSIC */
2656
2657         return (1);
2658
2659 #endif /* USE_MUSIC */
2660
2661 }
2662
2663
2664 /*
2665  * Delay for "x" milliseconds
2666  */
2667 static int Term_xtra_win_delay(int v)
2668 {
2669
2670 #ifdef WIN32
2671
2672         /* Sleep */
2673         Sleep(v);
2674
2675 #else /* WIN32 */
2676
2677         DWORD t;
2678         MSG msg;
2679
2680         /* Final count */
2681         t = GetTickCount() + v;
2682
2683         /* Wait for it */
2684         while (GetTickCount() < t)
2685         {
2686                 /* Handle messages */
2687                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
2688                 {
2689                         TranslateMessage(&msg);
2690                         DispatchMessage(&msg);
2691                 }
2692         }
2693
2694 #endif /* WIN32 */
2695
2696         /* Success */
2697         return (0);
2698 }
2699
2700
2701 /*
2702  * Do a "special thing"
2703  */
2704 static errr Term_xtra_win(int n, int v)
2705 {
2706         /* Handle a subset of the legal requests */
2707         switch (n)
2708         {
2709                 /* Make a bell sound */
2710                 case TERM_XTRA_NOISE:
2711                 {
2712                         return (Term_xtra_win_noise());
2713                 }
2714
2715                 /* Play a music */
2716                 case TERM_XTRA_MUSIC_BASIC:
2717                 case TERM_XTRA_MUSIC_DUNGEON:
2718                 case TERM_XTRA_MUSIC_QUEST:
2719                 case TERM_XTRA_MUSIC_TOWN:
2720                 {
2721                         return (Term_xtra_win_music(n, v));
2722                 }
2723
2724                 /* Make a special sound */
2725                 case TERM_XTRA_SOUND:
2726                 {
2727                         return (Term_xtra_win_sound(v));
2728                 }
2729
2730                 /* Process random events */
2731                 case TERM_XTRA_BORED:
2732                 {
2733                         return (Term_xtra_win_event(0));
2734                 }
2735
2736                 /* Process an event */
2737                 case TERM_XTRA_EVENT:
2738                 {
2739                         return (Term_xtra_win_event(v));
2740                 }
2741
2742                 /* Flush all events */
2743                 case TERM_XTRA_FLUSH:
2744                 {
2745                         return (Term_xtra_win_flush());
2746                 }
2747
2748                 /* Clear the screen */
2749                 case TERM_XTRA_CLEAR:
2750                 {
2751                         return (Term_xtra_win_clear());
2752                 }
2753
2754                 /* React to global changes */
2755                 case TERM_XTRA_REACT:
2756                 {
2757                         return (Term_xtra_win_react());
2758                 }
2759
2760                 /* Delay for some milliseconds */
2761                 case TERM_XTRA_DELAY:
2762                 {
2763                         return (Term_xtra_win_delay(v));
2764                 }
2765         }
2766
2767         return 1;
2768 }
2769
2770
2771
2772 /*
2773  * Low level graphics (Assumes valid input).
2774  *
2775  * Draw a "cursor" at (x,y), using a "yellow box".
2776  */
2777 static errr Term_curs_win(int x, int y)
2778 {
2779         term_data *td = (term_data*)(Term->data);
2780
2781         RECT rc;
2782         HDC hdc;
2783
2784         int tile_wid, tile_hgt;
2785
2786         if (td->map_active)
2787         {
2788                 tile_wid = td->map_tile_wid;
2789                 tile_hgt = td->map_tile_hgt;
2790         }
2791         else
2792         {
2793                 tile_wid = td->tile_wid;
2794                 tile_hgt = td->tile_hgt;
2795         }
2796
2797         /* Frame the grid */
2798         rc.left = x * tile_wid + td->size_ow1;
2799         rc.right = rc.left + tile_wid;
2800         rc.top = y * tile_hgt + td->size_oh1;
2801         rc.bottom = rc.top + tile_hgt;
2802
2803         /* Cursor is done as a yellow "box" */
2804         hdc = GetDC(td->w);
2805         FrameRect(hdc, &rc, hbrYellow);
2806         ReleaseDC(td->w, hdc);
2807
2808         /* Success */
2809         return 0;
2810 }
2811
2812
2813 /*
2814  * Low level graphics (Assumes valid input).
2815  *
2816  * Draw a "big cursor" at (x,y), using a "yellow box".
2817  */
2818 static errr Term_bigcurs_win(int x, int y)
2819 {
2820         term_data *td = (term_data*)(Term->data);
2821
2822         RECT rc;
2823         HDC hdc;
2824
2825         int tile_wid, tile_hgt;
2826
2827         if (td->map_active)
2828         {
2829                 /* Normal cursor in map window */
2830                 Term_curs_win(x, y);
2831                 return 0;
2832         }
2833         else
2834         {
2835                 tile_wid = td->tile_wid;
2836                 tile_hgt = td->tile_hgt;
2837         }
2838
2839         /* Frame the grid */
2840         rc.left = x * tile_wid + td->size_ow1;
2841         rc.right = rc.left + 2 * tile_wid;
2842         rc.top = y * tile_hgt + td->size_oh1;
2843         rc.bottom = rc.top + tile_hgt;
2844
2845         /* Cursor is done as a yellow "box" */
2846         hdc = GetDC(td->w);
2847         FrameRect(hdc, &rc, hbrYellow);
2848         ReleaseDC(td->w, hdc);
2849
2850         /* Success */
2851         return 0;
2852 }
2853
2854
2855 /*
2856  * Low level graphics (Assumes valid input).
2857  *
2858  * Erase a "block" of "n" characters starting at (x,y).
2859  */
2860 static errr Term_wipe_win(int x, int y, int n)
2861 {
2862         term_data *td = (term_data*)(Term->data);
2863
2864         HDC hdc;
2865         RECT rc;
2866
2867         /* Rectangle to erase in client coords */
2868         rc.left = x * td->tile_wid + td->size_ow1;
2869         rc.right = rc.left + n * td->tile_wid;
2870         rc.top = y * td->tile_hgt + td->size_oh1;
2871         rc.bottom = rc.top + td->tile_hgt;
2872
2873         hdc = GetDC(td->w);
2874         SetBkColor(hdc, RGB(0, 0, 0));
2875         SelectObject(hdc, td->font_id);
2876         /* bg */
2877         if (use_bg)
2878                 DrawBG(hdc, &rc);
2879         else
2880                 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
2881         ReleaseDC(td->w, hdc);
2882
2883         /* Success */
2884         return 0;
2885 }
2886
2887
2888 /*
2889  * Low level graphics.  Assumes valid input.
2890  *
2891  * Draw several ("n") chars, with an attr, at a given location.
2892  *
2893  * All "graphic" data is handled by "Term_pict_win()", below.
2894  *
2895  * One would think there is a more efficient method for telling a window
2896  * what color it should be using to draw with, but perhaps simply changing
2897  * it every time is not too inefficient.  
2898  */
2899 static errr Term_text_win(int x, int y, int n, TERM_COLOR a, concptr s)
2900 {
2901         term_data *td = (term_data*)(Term->data);
2902         RECT rc;
2903         HDC hdc;
2904
2905 #if 1 /* #ifdef JP */
2906         static HBITMAP  WALL;
2907         static HBRUSH   myBrush, oldBrush;
2908         static HPEN     oldPen;
2909         static bool init_done = FALSE;
2910
2911         if (!init_done){
2912                 WALL = LoadBitmap(hInstance, AppName);
2913                 myBrush = CreatePatternBrush(WALL);
2914                 init_done = TRUE;
2915         }
2916 #endif
2917
2918         /* Total rectangle */
2919         rc.left = x * td->tile_wid + td->size_ow1;
2920         rc.right = rc.left + n * td->tile_wid;
2921         rc.top = y * td->tile_hgt + td->size_oh1;
2922         rc.bottom = rc.top + td->tile_hgt;
2923
2924         /* Acquire DC */
2925         hdc = GetDC(td->w);
2926
2927         /* Background color */
2928         SetBkColor(hdc, RGB(0, 0, 0));
2929
2930         /* Foreground color */
2931         if (colors16)
2932         {
2933                 SetTextColor(hdc, PALETTEINDEX(win_pal[a]));
2934         }
2935         else if (paletted)
2936         {
2937                 SetTextColor(hdc, win_clr[a&0x0F]);
2938         }
2939         else
2940         {
2941                 SetTextColor(hdc, win_clr[a]);
2942         }
2943
2944         /* Use the font */
2945         SelectObject(hdc, td->font_id);
2946         
2947         /* bg */
2948         if (use_bg) SetBkMode(hdc, TRANSPARENT);
2949
2950         /* Bizarre size */
2951         if (td->bizarre ||
2952             (td->tile_hgt != td->font_hgt) ||
2953             (td->tile_wid != td->font_wid))
2954         {
2955                 int i;
2956
2957                 /* Erase complete rectangle */
2958                 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
2959                 
2960                 /* bg */
2961                 if (use_bg) DrawBG(hdc, &rc);
2962
2963                 /* New rectangle */
2964                 rc.left += ((td->tile_wid - td->font_wid) / 2);
2965                 rc.right = rc.left + td->font_wid;
2966                 rc.top += ((td->tile_hgt - td->font_hgt) / 2);
2967                 rc.bottom = rc.top + td->font_hgt;
2968
2969                 /* Dump each character */
2970                 for (i = 0; i < n; i++)
2971                 {
2972 #ifdef JP
2973                         if (use_bigtile && *(s+i)=="■"[0] && *(s+i+1)=="■"[1])
2974                         {
2975                                 rc.right += td->font_wid;
2976
2977                                 oldBrush = SelectObject(hdc, myBrush);
2978                                 oldPen = SelectObject(hdc, GetStockObject(NULL_PEN) );
2979
2980                                 /* Dump the wall */
2981                                 Rectangle(hdc, rc.left, rc.top, rc.right+1, rc.bottom+1);
2982
2983                                 SelectObject(hdc, oldBrush);
2984                                 SelectObject(hdc, oldPen);
2985                                 rc.right -= td->font_wid;
2986
2987                                 /* Advance */
2988                                 i++;
2989                                 rc.left += 2 * td->tile_wid;
2990                                 rc.right += 2 * td->tile_wid;
2991                         }
2992                         else if ( iskanji(*(s+i)) )  /*  2バイト文字  */
2993                         {
2994                                 rc.right += td->font_wid;
2995                                 /* Dump the text */
2996                                 ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc,
2997                                        s+i, 2, NULL);
2998                                 rc.right -= td->font_wid;
2999
3000                                 /* Advance */
3001                                 i++;
3002                                 rc.left += 2 * td->tile_wid;
3003                                 rc.right += 2 * td->tile_wid;
3004                         } else if (*(s+i)==127){
3005                                 oldBrush = SelectObject(hdc, myBrush);
3006                                 oldPen = SelectObject(hdc, GetStockObject(NULL_PEN) );
3007
3008                                 /* Dump the wall */
3009                                 Rectangle(hdc, rc.left, rc.top, rc.right+1, rc.bottom+1);
3010
3011                                 SelectObject(hdc, oldBrush);
3012                                 SelectObject(hdc, oldPen);
3013
3014                                 /* Advance */
3015                                 rc.left += td->tile_wid;
3016                                 rc.right += td->tile_wid;
3017                         } else {
3018                                 /* Dump the text */
3019                                 ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc, s+i, 1, NULL);
3020
3021                                 /* Advance */
3022                                 rc.left += td->tile_wid;
3023                                 rc.right += td->tile_wid;
3024                         }
3025 #else
3026 #if 1
3027                         if (*(s+i)==127){
3028                                 oldBrush = SelectObject(hdc, myBrush);
3029                                 oldPen = SelectObject(hdc, GetStockObject(NULL_PEN) );
3030
3031                                 /* Dump the wall */
3032                                 Rectangle(hdc, rc.left, rc.top, rc.right+1, rc.bottom+1);
3033
3034                                 SelectObject(hdc, oldBrush);
3035                                 SelectObject(hdc, oldPen);
3036
3037                                 /* Advance */
3038                                 rc.left += td->tile_wid;
3039                                 rc.right += td->tile_wid;
3040                         } else {
3041                                 /* Dump the text */
3042                                 ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc,
3043                                        s+i, 1, NULL);
3044
3045                                 /* Advance */
3046                                 rc.left += td->tile_wid;
3047                                 rc.right += td->tile_wid;
3048                         }
3049 #else
3050                         /* Dump the text */
3051                         ExtTextOut(hdc, rc.left, rc.top, 0, &rc,
3052                                    s+i, 1, NULL);
3053
3054                         /* Advance */
3055                         rc.left += td->tile_wid;
3056                         rc.right += td->tile_wid;
3057 #endif
3058 #endif
3059
3060                 }
3061         }
3062
3063         /* Normal size */
3064         else
3065         {
3066                 /* Dump the text */
3067                 ExtTextOut(hdc, rc.left, rc.top, ETO_OPAQUE | ETO_CLIPPED, &rc,
3068                            s, n, NULL);
3069         }
3070
3071         /* Release DC */
3072         ReleaseDC(td->w, hdc);
3073
3074         /* Success */
3075         return 0;
3076 }
3077
3078
3079 /*
3080  * Low level graphics.  Assumes valid input.
3081  *
3082  * Draw an array of "special" attr/char pairs at the given location.
3083  *
3084  * We use the "Term_pict_win()" function for "graphic" data, which are
3085  * encoded by setting the "high-bits" of both the "attr" and the "char"
3086  * data.  We use the "attr" to represent the "row" of the main bitmap,
3087  * and the "char" to represent the "col" of the main bitmap.  The use
3088  * of this function is induced by the "higher_pict" flag.
3089  *
3090  * If "graphics" is not available, we simply "wipe" the given grids.
3091  */
3092 static errr Term_pict_win(TERM_LEN x, TERM_LEN y, int n, const TERM_COLOR *ap, concptr cp, const TERM_COLOR *tap, concptr tcp)
3093 {
3094         term_data *td = (term_data*)(Term->data);
3095
3096 #ifdef USE_GRAPHICS
3097
3098         int i;
3099         TERM_LEN x1, y1, w1, h1, tw1, th1;
3100         TERM_LEN x2, y2, w2, h2, tw2 = 0;
3101         TERM_LEN x3, y3;
3102
3103         HDC hdcMask = NULL;
3104
3105         HDC hdc;
3106         HDC hdcSrc;
3107         HBITMAP hbmSrcOld;
3108         if (!use_graphics)
3109         {
3110                 /* Erase the grids */
3111                 return (Term_wipe_win(x, y, n));
3112         }
3113
3114         /* Size of bitmap cell */
3115         w1 = infGraph.CellWidth;
3116         h1 = infGraph.CellHeight;
3117         tw1 = infGraph.TileWidth;
3118         th1 = infGraph.TileHeight;
3119
3120         /* Size of window cell */
3121         if (td->map_active)
3122         {
3123                 w2 = td->map_tile_wid;
3124                 h2 = td->map_tile_hgt;
3125         }
3126         else
3127         {
3128                 w2 = td->tile_wid;
3129                 h2 = td->tile_hgt;
3130                 tw2 = w2;
3131
3132                 /* big tile mode */
3133                 if (use_bigtile) tw2 *= 2;
3134         }
3135
3136         /* Location of window cell */
3137         x2 = x * w2 + td->size_ow1 + infGraph.OffsetX;
3138         y2 = y * h2 + td->size_oh1 + infGraph.OffsetY;
3139
3140         /* Info */
3141         hdc = GetDC(td->w);
3142
3143         /* More info */
3144         hdcSrc = CreateCompatibleDC(hdc);
3145         hbmSrcOld = SelectObject(hdcSrc, infGraph.hBitmap);
3146
3147         if (arg_graphics == GRAPHICS_ADAM_BOLT || arg_graphics == GRAPHICS_HENGBAND)
3148         {
3149                 hdcMask = CreateCompatibleDC(hdc);
3150                 SelectObject(hdcMask, infMask.hBitmap);
3151         }
3152
3153         /* Draw attr/char pairs */
3154         for (i = 0; i < n; i++, x2 += w2)
3155         {
3156                 TERM_COLOR a = ap[i];
3157                 char c = cp[i];
3158
3159
3160                 /* Extract picture */
3161                 int row = (a & 0x7F);
3162                 int col = (c & 0x7F);
3163
3164                 /* Location of bitmap cell */
3165                 x1 = col * w1;
3166                 y1 = row * h1;
3167
3168                 if (arg_graphics == GRAPHICS_ADAM_BOLT || arg_graphics == GRAPHICS_HENGBAND)
3169                 {
3170                         x3 = (tcp[i] & 0x7F) * w1;
3171                         y3 = (tap[i] & 0x7F) * h1;
3172                         tw2 = tw2 * w1 / tw1;
3173                         h2 = h2 * h1 / th1;
3174
3175                         /* Perfect size */
3176                         if ((tw1 == tw2) && (th1 == h2))
3177                         {
3178                                 /* Copy the terrain picture from the bitmap to the window */
3179                                 BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, SRCCOPY);
3180
3181                                 /* Mask out the tile */
3182                                 BitBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, SRCAND);
3183
3184                                 /* Draw the tile */
3185                                 BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCPAINT);
3186                         }
3187
3188                         /* Need to stretch */
3189                         else
3190                         {
3191                                 /* Set the correct mode for stretching the tiles */
3192                                 SetStretchBltMode(hdc, COLORONCOLOR);
3193
3194                                 /* Copy the terrain picture from the bitmap to the window */
3195                                 StretchBlt(hdc, x2, y2, tw2, h2, hdcMask, x3, y3, w1, h1, SRCAND);
3196
3197                                 StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, w1, h1, SRCPAINT);
3198
3199                                 /* Only draw if terrain and overlay are different */
3200                                 if ((x1 != x3) || (y1 != y3))
3201                                 {
3202                                         /* Mask out the tile */
3203                                         StretchBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, w1, h1, SRCAND);
3204
3205                                         /* Draw the tile */
3206                                         StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCPAINT);
3207                                 }
3208                         }
3209                 }
3210                 else
3211                 {
3212                         /* Perfect size */
3213                         if ((w1 == tw2) && (h1 == h2))
3214                         {
3215                                 /* Copy the picture from the bitmap to the window */
3216                                 BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCCOPY);
3217                         }
3218
3219                         /* Need to stretch */
3220                         else
3221                         {
3222                                 /* Set the correct mode for stretching the tiles */
3223                                 SetStretchBltMode(hdc, COLORONCOLOR);
3224
3225                                 /* Copy the picture from the bitmap to the window */
3226                                 StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCCOPY);
3227                         }
3228                 }
3229         }
3230
3231         /* Release */
3232         SelectObject(hdcSrc, hbmSrcOld);
3233         DeleteDC(hdcSrc);
3234
3235         if (arg_graphics == GRAPHICS_ADAM_BOLT || arg_graphics == GRAPHICS_HENGBAND)
3236         {
3237                 /* Release */
3238                 SelectObject(hdcMask, hbmSrcOld);
3239                 DeleteDC(hdcMask);
3240         }
3241
3242         /* Release */
3243         ReleaseDC(td->w, hdc);
3244
3245 #else /* USE_GRAPHICS */
3246
3247         /* Just erase this grid */
3248         return (Term_wipe_win(x, y, n));
3249
3250 #endif /* USE_GRAPHICS */
3251
3252         /* Success */
3253         return 0;
3254 }
3255
3256
3257 static void windows_map(void)
3258 {
3259         term_data *td = &data[0];
3260         TERM_COLOR a;
3261         char c;
3262         TERM_LEN x, min_x, max_x;
3263         TERM_LEN y, min_y, max_y;
3264
3265         TERM_COLOR ta;
3266         char tc;
3267
3268         /* Only in graphics mode */
3269         if (!use_graphics) return;
3270         Term_xtra_win_clear();
3271
3272         td->map_tile_wid = (td->tile_wid * td->cols) / MAX_WID;
3273         td->map_tile_hgt = (td->tile_hgt * td->rows) / MAX_HGT;
3274         td->map_active = TRUE;
3275
3276         {
3277                 min_x = 0;
3278                 min_y = 0;
3279                 max_x = current_floor_ptr->width;
3280                 max_y = current_floor_ptr->height;
3281         }
3282
3283         /* Draw the map */
3284         for (x = min_x; x < max_x; x++)
3285         {
3286                 for (y = min_y; y < max_y; y++)
3287                 {
3288                         map_info(y, x, &a, (char*)&c, &ta, (char*)&tc);
3289
3290                         /* Ignore non-graphics */
3291                         if ((a & 0x80) && (c & 0x80))
3292                         {
3293                                 Term_pict_win(x - min_x, y - min_y, 1, &a, &c, &ta, &tc);
3294                         }
3295                 }
3296         }
3297
3298         /* Hilite the player */
3299         Term_curs_win(p_ptr->x - min_x, p_ptr->y - min_y);
3300
3301         /* Wait for a keypress, flush key buffer */
3302         Term_inkey(&c, TRUE, TRUE);
3303         Term_flush();
3304
3305         /* Switch off the map display */
3306         td->map_active = FALSE;
3307
3308         /* Restore screen */
3309         Term_xtra_win_clear();
3310         Term_redraw();
3311 }
3312
3313
3314 /*** Other routines ***/
3315
3316
3317 /*
3318  * Create and initialize a "term_data" given a title
3319  */
3320 static void term_data_link(term_data *td)
3321 {
3322         term *t = &td->t;
3323
3324         /* Initialize the term */
3325         term_init(t, td->cols, td->rows, td->keys);
3326
3327         /* Use a "software" cursor */
3328         t->soft_cursor = TRUE;
3329
3330         /* Use "Term_pict" for "graphic" data */
3331         t->higher_pict = TRUE;
3332
3333         /* Erase with "white space" */
3334         t->attr_blank = TERM_WHITE;
3335         t->char_blank = ' ';
3336
3337 #if 0
3338         /* Prepare the init/nuke hooks */
3339         t->init_hook = Term_init_win;
3340         t->nuke_hook = Term_nuke_win;
3341 #endif
3342
3343         /* Prepare the template hooks */
3344         t->user_hook = Term_user_win;
3345         t->xtra_hook = Term_xtra_win;
3346         t->curs_hook = Term_curs_win;
3347         t->bigcurs_hook = Term_bigcurs_win;
3348         t->wipe_hook = Term_wipe_win;
3349         t->text_hook = Term_text_win;
3350         t->pict_hook = Term_pict_win;
3351
3352         /* Remember where we came from */
3353         t->data = (vptr)(td);
3354 }
3355
3356
3357 /*
3358  * Create the windows
3359  *
3360  * First, instantiate the "default" values, then read the "ini_file"
3361  * to over-ride selected values, then create the windows, and fonts.
3362  *
3363  * Must use SW_SHOW not SW_SHOWNA, since on 256 color display
3364  * must make active to realize the palette.  
3365  */
3366 static void init_windows(void)
3367 {
3368         int i;
3369
3370         term_data *td;
3371
3372 #if 0 /* #ifndef JP */
3373         char buf[1024];
3374 #endif
3375
3376         /* Main window */
3377         td = &data[0];
3378         WIPE(td, term_data);
3379 #ifdef JP
3380         td->s = "変愚蛮怒";
3381 #else
3382         td->s = angband_term_name[0];
3383 #endif
3384
3385         td->keys = 1024;
3386         td->rows = 24;
3387         td->cols = 80;
3388         td->visible = TRUE;
3389         td->size_ow1 = 2;
3390         td->size_ow2 = 2;
3391         td->size_oh1 = 2;
3392         td->size_oh2 = 2;
3393         td->pos_x = 7 * 30;
3394         td->pos_y = 7 * 20;
3395         td->posfix = FALSE;
3396 #if 1 /* #ifdef JP */
3397         td->bizarre = TRUE;
3398 #endif
3399         /* Sub windows */
3400         for (i = 1; i < MAX_TERM_DATA; i++)
3401         {
3402                 td = &data[i];
3403                 WIPE(td, term_data);
3404                 td->s = angband_term_name[i];
3405                 td->keys = 16;
3406                 td->rows = 24;
3407                 td->cols = 80;
3408                 td->visible = FALSE;
3409                 td->size_ow1 = 1;
3410                 td->size_ow2 = 1;
3411                 td->size_oh1 = 1;
3412                 td->size_oh2 = 1;
3413                 td->pos_x = (7 - i) * 30;
3414                 td->pos_y = (7 - i) * 20;
3415                 td->posfix = FALSE;
3416 #if 1 /* #ifdef JP */
3417                         td->bizarre = TRUE;
3418 #endif
3419         }
3420
3421
3422         /* Load prefs */
3423         load_prefs();
3424
3425
3426         /* Main window (need these before term_getsize gets called) */
3427         td = &data[0];
3428         td->dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU |
3429                        WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION |
3430                        WS_VISIBLE);
3431         td->dwExStyle = 0;
3432         td->visible = TRUE;
3433
3434         /* Sub windows (need these before term_getsize gets called) */
3435         for (i = 1; i < MAX_TERM_DATA; i++)
3436         {
3437                 td = &data[i];
3438                 td->dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU);
3439                 td->dwExStyle = (WS_EX_TOOLWINDOW);
3440         }
3441
3442
3443         /* All windows */
3444         for (i = 0; i < MAX_TERM_DATA; i++)
3445         {
3446                 td = &data[i];
3447
3448 #if 1 /* #ifdef JP */
3449                 strncpy(td->lf.lfFaceName, td->font_want, LF_FACESIZE);
3450                 td->lf.lfCharSet = DEFAULT_CHARSET;
3451                 td->lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
3452                 /* Activate the chosen font */
3453                 term_force_font(td, NULL);
3454                 if(!td->tile_wid) td->tile_wid = td->font_wid;
3455                 if(!td->tile_hgt) td->tile_hgt = td->font_hgt;
3456 #else
3457                 /* Access the standard font file */
3458                 path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_FONT, td->font_want);
3459
3460                 /* Activate the chosen font */
3461                 if (term_force_font(td, buf))
3462                 {
3463                         /* Access the standard font file */
3464                         path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_FONT, "8X13.FON");
3465
3466                         /* Force the use of that font */
3467                         (void)term_force_font(td, buf);
3468
3469                         td->tile_wid = 8;
3470                         td->tile_hgt = 13;
3471
3472                         /* Assume not bizarre */
3473                         td->bizarre = FALSE;
3474                 }
3475 #endif
3476
3477
3478                 /* Analyze the font */
3479                 term_getsize(td);
3480
3481                 /* Resize the window */
3482                 term_window_resize(td);
3483         }
3484
3485
3486         /* Sub windows (reverse order) */
3487         for (i = MAX_TERM_DATA - 1; i >= 1; --i)
3488         {
3489                 td = &data[i];
3490
3491                 my_td = td;
3492                 td->w = CreateWindowEx(td->dwExStyle, AngList,
3493                                        td->s, td->dwStyle,
3494                                        td->pos_x, td->pos_y,
3495                                        td->size_wid, td->size_hgt,
3496                                        HWND_DESKTOP, NULL, hInstance, NULL);
3497                 my_td = NULL;
3498                 if (!td->w) quit(_("サブウィンドウに作成に失敗しました", "Failed to create sub-window"));
3499
3500                 if (td->visible)
3501                 {
3502                         td->size_hack = TRUE;
3503                         ShowWindow(td->w, SW_SHOW);
3504                         td->size_hack = FALSE;
3505                 }
3506
3507                 term_data_link(td);
3508                 angband_term[i] = &td->t;
3509
3510                 if (td->visible)
3511                 {
3512                         /* Activate the window */
3513                         SetActiveWindow(td->w);
3514                 }
3515
3516                 if (data[i].posfix)
3517                 {
3518                         term_window_pos(&data[i], HWND_TOPMOST);
3519                 }
3520                 else
3521                 {
3522                         term_window_pos(&data[i], td->w);
3523                 }
3524         }
3525
3526
3527         /* Main window */
3528         td = &data[0];
3529
3530         /* Main window */
3531         my_td = td;
3532         td->w = CreateWindowEx(td->dwExStyle, AppName,
3533                                td->s, td->dwStyle,
3534                                td->pos_x, td->pos_y,
3535                                td->size_wid, td->size_hgt,
3536                                HWND_DESKTOP, NULL, hInstance, NULL);
3537         my_td = NULL;
3538         if (!td->w) quit(_("メインウィンドウの作成に失敗しました", "Failed to create Angband window"));
3539
3540         term_data_link(td);
3541         angband_term[0] = &td->t;
3542         normsize.x = td->cols;
3543         normsize.y = td->rows;
3544
3545         /* Activate the main window */
3546         if (win_maximized) ShowWindow(td->w, SW_SHOWMAXIMIZED);
3547         else ShowWindow(td->w, SW_SHOW);
3548
3549         /* Bring main window back to top */
3550         SetWindowPos(td->w, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
3551
3552
3553         /* New palette */
3554         (void)new_palette();
3555
3556
3557         /* Create a "brush" for drawing the "cursor" */
3558         hbrYellow = CreateSolidBrush(win_clr[TERM_YELLOW]);
3559
3560
3561         /* Process pending messages */
3562         (void)Term_xtra_win_flush();
3563 }
3564
3565
3566
3567 /*
3568  * Prepare the menus
3569  */
3570 static void setup_menus(void)
3571 {
3572         int i;
3573
3574         HMENU hm = GetMenu(data[0].w);
3575
3576
3577         /* Menu "File", Disable all */
3578         EnableMenuItem(hm, IDM_FILE_NEW,
3579                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3580         EnableMenuItem(hm, IDM_FILE_OPEN,
3581                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3582         EnableMenuItem(hm, IDM_FILE_SAVE,
3583                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3584         EnableMenuItem(hm, IDM_FILE_EXIT,
3585                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3586         EnableMenuItem(hm, IDM_FILE_SCORE,
3587                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3588
3589
3590         /* No character available */
3591         if (!current_world_ptr->character_generated)
3592         {
3593                 /* Menu "File", Item "New" */
3594                 EnableMenuItem(hm, IDM_FILE_NEW, MF_BYCOMMAND | MF_ENABLED);
3595
3596                 /* Menu "File", Item "Open" */
3597                 EnableMenuItem(hm, IDM_FILE_OPEN, MF_BYCOMMAND | MF_ENABLED);
3598         }
3599
3600         /* A character available */
3601         if (current_world_ptr->character_generated)
3602         {
3603                 /* Menu "File", Item "Save" */
3604                 EnableMenuItem(hm, IDM_FILE_SAVE,
3605                            MF_BYCOMMAND | MF_ENABLED);
3606         }
3607
3608         /* Menu "File", Item "Exit" */
3609         EnableMenuItem(hm, IDM_FILE_EXIT,
3610                        MF_BYCOMMAND | MF_ENABLED);
3611
3612         EnableMenuItem(hm, IDM_FILE_SCORE,
3613                        MF_BYCOMMAND | MF_ENABLED);
3614
3615
3616         /* Menu "Window::Visibility" */
3617         for (i = 0; i < MAX_TERM_DATA; i++)
3618         {
3619                 EnableMenuItem(hm, IDM_WINDOW_VIS_0 + i,
3620                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3621
3622                 CheckMenuItem(hm, IDM_WINDOW_VIS_0 + i,
3623                               (data[i].visible ? MF_CHECKED : MF_UNCHECKED));
3624
3625                 EnableMenuItem(hm, IDM_WINDOW_VIS_0 + i,
3626                                MF_BYCOMMAND | MF_ENABLED);
3627         }
3628
3629         /* Menu "Window::Font" */
3630         for (i = 0; i < MAX_TERM_DATA; i++)
3631         {
3632                 EnableMenuItem(hm, IDM_WINDOW_FONT_0 + i,
3633                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3634
3635                 if (data[i].visible)
3636                 {
3637                         EnableMenuItem(hm, IDM_WINDOW_FONT_0 + i,
3638                                        MF_BYCOMMAND | MF_ENABLED);
3639                 }
3640         }
3641
3642         /* Menu "Window::Window Position Fix" */
3643         for (i = 0; i < MAX_TERM_DATA; i++)
3644         {
3645                 EnableMenuItem(hm, IDM_WINDOW_POS_0 + i,
3646                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3647
3648                 CheckMenuItem(hm, IDM_WINDOW_POS_0 + i,
3649                               (data[i].posfix ? MF_CHECKED : MF_UNCHECKED));
3650
3651                 if (data[i].visible)
3652                 {
3653                         EnableMenuItem(hm, IDM_WINDOW_POS_0 + i,
3654                                        MF_BYCOMMAND | MF_ENABLED);
3655                 }
3656         }
3657
3658         /* Menu "Window::Bizarre Display" */
3659         for (i = 0; i < MAX_TERM_DATA; i++)
3660         {
3661                 EnableMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
3662                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3663
3664                 CheckMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
3665                               (data[i].bizarre ? MF_CHECKED : MF_UNCHECKED));
3666
3667                 if (data[i].visible)
3668                 {
3669                         EnableMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
3670                                    MF_BYCOMMAND | MF_ENABLED);
3671
3672                 }
3673         }
3674
3675         /* Menu "Window::Increase Tile Width" */
3676         for (i = 0; i < MAX_TERM_DATA; i++)
3677         {
3678                 EnableMenuItem(hm, IDM_WINDOW_I_WID_0 + i,
3679                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3680
3681                 if (data[i].visible)
3682                 {
3683                         EnableMenuItem(hm, IDM_WINDOW_I_WID_0 + i,
3684                                    MF_BYCOMMAND | MF_ENABLED);
3685
3686                 }
3687         }
3688
3689         /* Menu "Window::Decrease Tile Width" */
3690         for (i = 0; i < MAX_TERM_DATA; i++)
3691         {
3692                 EnableMenuItem(hm, IDM_WINDOW_D_WID_0 + i,
3693                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3694
3695                 if (data[i].visible)
3696                 {
3697                         EnableMenuItem(hm, IDM_WINDOW_D_WID_0 + i,
3698                                    MF_BYCOMMAND | MF_ENABLED);
3699
3700                 }
3701         }
3702
3703         /* Menu "Window::Increase Tile Height" */
3704         for (i = 0; i < MAX_TERM_DATA; i++)
3705         {
3706                 EnableMenuItem(hm, IDM_WINDOW_I_HGT_0 + i,
3707                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3708
3709                 if (data[i].visible)
3710                 {
3711                         EnableMenuItem(hm, IDM_WINDOW_I_HGT_0 + i,
3712                                    MF_BYCOMMAND | MF_ENABLED);
3713
3714                 }
3715         }
3716
3717         /* Menu "Window::Decrease Tile Height" */
3718         for (i = 0; i < MAX_TERM_DATA; i++)
3719         {
3720                 EnableMenuItem(hm, IDM_WINDOW_D_HGT_0 + i,
3721                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3722
3723                 if (data[i].visible)
3724                 {
3725                         EnableMenuItem(hm, IDM_WINDOW_D_HGT_0 + i,
3726                                    MF_BYCOMMAND | MF_ENABLED);
3727
3728                 }
3729         }
3730
3731         /* Menu "Options", disable all */
3732         EnableMenuItem(hm, IDM_OPTIONS_NO_GRAPHICS,
3733                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3734         EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
3735                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3736         EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
3737                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3738         EnableMenuItem(hm, IDM_OPTIONS_BIGTILE,
3739                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3740         EnableMenuItem(hm, IDM_OPTIONS_SOUND,
3741                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3742 #ifndef JP
3743         EnableMenuItem(hm, IDM_OPTIONS_SAVER,
3744                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3745 #endif
3746
3747         /* Menu "Options", Item "Map" */
3748         if (use_graphics != GRAPHICS_NONE)
3749                 EnableMenuItem(GetMenu(data[0].w), IDM_OPTIONS_MAP, MF_BYCOMMAND | MF_ENABLED);
3750         else
3751                 EnableMenuItem(GetMenu(data[0].w), IDM_OPTIONS_MAP,
3752                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3753
3754         /* Menu "Options", update all */
3755         CheckMenuItem(hm, IDM_OPTIONS_NO_GRAPHICS,
3756                       (arg_graphics == GRAPHICS_NONE ? MF_CHECKED : MF_UNCHECKED));
3757         CheckMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
3758                       (arg_graphics == GRAPHICS_ORIGINAL ? MF_CHECKED : MF_UNCHECKED));
3759         CheckMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
3760                       (arg_graphics == GRAPHICS_ADAM_BOLT ? MF_CHECKED : MF_UNCHECKED));
3761         CheckMenuItem(hm, IDM_OPTIONS_NEW2_GRAPHICS,
3762                       (arg_graphics == GRAPHICS_HENGBAND ? MF_CHECKED : MF_UNCHECKED));
3763         CheckMenuItem(hm, IDM_OPTIONS_BIGTILE,
3764                       (arg_bigtile ? MF_CHECKED : MF_UNCHECKED));
3765         CheckMenuItem(hm, IDM_OPTIONS_MUSIC,
3766                       (arg_music ? MF_CHECKED : MF_UNCHECKED));
3767         CheckMenuItem(hm, IDM_OPTIONS_SOUND,
3768                       (arg_sound ? MF_CHECKED : MF_UNCHECKED));
3769         CheckMenuItem(hm, IDM_OPTIONS_BG,
3770                       (use_bg ? MF_CHECKED : MF_UNCHECKED));
3771 #ifndef JP
3772         CheckMenuItem(hm, IDM_OPTIONS_SAVER,
3773                       (hwndSaver ? MF_CHECKED : MF_UNCHECKED));
3774 #endif
3775
3776 #ifdef USE_GRAPHICS
3777         /* Menu "Options", Item "Graphics" */
3778         EnableMenuItem(hm, IDM_OPTIONS_NO_GRAPHICS, MF_ENABLED);
3779         /* Menu "Options", Item "Graphics" */
3780         EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS, MF_ENABLED);
3781         /* Menu "Options", Item "Graphics" */
3782         EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS, MF_ENABLED);
3783         /* Menu "Options", Item "Graphics" */
3784         EnableMenuItem(hm, IDM_OPTIONS_BIGTILE, MF_ENABLED);
3785 #endif /* USE_GRAPHICS */
3786
3787 #ifdef USE_SOUND
3788         /* Menu "Options", Item "Sound" */
3789         EnableMenuItem(hm, IDM_OPTIONS_SOUND, MF_ENABLED);
3790 #endif /* USE_SOUND */
3791
3792 #ifdef USE_SAVER
3793         /* Menu "Options", Item "ScreenSaver" */
3794         EnableMenuItem(hm, IDM_OPTIONS_SAVER,
3795                        MF_BYCOMMAND | MF_ENABLED);
3796 #endif /* USE_SAVER */
3797 }
3798
3799
3800 /*
3801  * Check for double clicked (or dragged) savefile
3802  *
3803  * Apparently, Windows copies the entire filename into the first
3804  * piece of the "command line string".  Perhaps we should extract
3805  * the "basename" of that filename and append it to the "save" dir.
3806  */
3807 static void check_for_save_file(LPSTR cmd_line)
3808 {
3809         char *s;
3810
3811         /* First arg */
3812         s = cmd_line;
3813
3814         /* No args */
3815         if (!*s) return;
3816
3817         /* Extract filename */
3818         strcat(savefile, s);
3819
3820         /* Validate the file */
3821         validate_file(savefile);
3822
3823         /* Game in progress */
3824         game_in_progress = TRUE;
3825
3826         /* Play game */
3827         play_game(FALSE);
3828 }
3829
3830
3831 /*
3832  * Process a menu command
3833  */
3834 static void process_menus(WORD wCmd)
3835 {
3836         int i;
3837
3838         term_data *td;
3839
3840         OPENFILENAME ofn;
3841
3842         /* Analyze */
3843         switch (wCmd)
3844         {
3845                 /* New game */
3846                 case IDM_FILE_NEW:
3847                 {
3848                         if (!initialized)
3849                         {
3850                                 plog(_("まだ初期化中です...", "You cannot do that yet..."));
3851                         }
3852                         else if (game_in_progress)
3853                         {
3854                                 plog(_("プレイ中は新しいゲームを始めることができません!", "You can't start a new game while you're still playing!"));
3855                         }
3856                         else
3857                         {
3858                                 game_in_progress = TRUE;
3859                                 Term_flush();
3860                                 play_game(TRUE);
3861                                 quit(NULL);
3862                         }
3863                         break;
3864                 }
3865
3866                 /* Open game */
3867                 case IDM_FILE_OPEN:
3868                 {
3869                         if (!initialized)
3870                         {
3871                                 plog(_("まだ初期化中です...", "You cannot do that yet..."));
3872                         }
3873                         else if (game_in_progress)
3874                         {
3875                                 plog(_("プレイ中はゲームをロードすることができません!", "You can't open a new game while you're still playing!"));
3876                         }
3877                         else
3878                         {
3879                                 memset(&ofn, 0, sizeof(ofn));
3880                                 ofn.lStructSize = sizeof(ofn);
3881                                 ofn.hwndOwner = data[0].w;
3882                                 ofn.lpstrFilter = "Save Files (*.)\0*\0";
3883                                 ofn.nFilterIndex = 1;
3884                                 ofn.lpstrFile = savefile;
3885                                 ofn.nMaxFile = 1024;
3886                                 ofn.lpstrInitialDir = ANGBAND_DIR_SAVE;
3887                                 ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
3888
3889                                 if (GetOpenFileName(&ofn))
3890                                 {
3891                                         /* Load 'savefile' */
3892                                         validate_file(savefile);
3893                                         game_in_progress = TRUE;
3894                                         Term_flush();
3895                                         play_game(FALSE);
3896                                         quit(NULL);
3897                                 }
3898                         }
3899                         break;
3900                 }
3901
3902                 /* Save game */
3903                 case IDM_FILE_SAVE:
3904                 {
3905                         if (game_in_progress && current_world_ptr->character_generated)
3906                         {
3907                                 if (!can_save)
3908                                 {
3909                                         plog(_("今はセーブすることは出来ません。", "You may not do that right now."));
3910                                         break;
3911                                 }
3912
3913                                 /* Hack -- Forget messages */
3914                                 msg_flag = FALSE;
3915
3916                                 /* Save the game */
3917 #ifdef ZANGBAND
3918                                 do_cmd_save_game(FALSE);
3919 #else /* ZANGBAND */
3920                                 do_cmd_save_game();
3921 #endif /* ZANGBAND */
3922                         }
3923                         else
3924                         {
3925                                 plog(_("今、セーブすることは出来ません。", "You may not do that right now."));
3926                         }
3927                         break;
3928                 }
3929
3930                 case IDM_FILE_EXIT:
3931                 {
3932                         if (game_in_progress && current_world_ptr->character_generated)
3933                         {
3934                                 if (!can_save)
3935                                 {
3936                                         plog(_("今は終了できません。", "You may not do that right now."));
3937                                         break;
3938                                 }
3939
3940                                 /* Hack -- Forget messages */
3941                                 msg_flag = FALSE;
3942
3943                                 forget_lite();
3944                                 forget_view();
3945                                 clear_mon_lite();
3946
3947                                 /* Save the game */
3948 #ifdef ZANGBAND
3949                                 /* do_cmd_save_game(FALSE); */
3950 #else /* ZANGBAND */
3951                                 /* do_cmd_save_game(); */
3952 #endif /* ZANGBAND */
3953                                 Term_key_push(SPECIAL_KEY_QUIT);
3954                                 break;
3955                         }
3956                         quit(NULL);
3957                         break;
3958                 }
3959
3960                 /* Show scores */
3961                 case IDM_FILE_SCORE:
3962                 {
3963                         char buf[1024];
3964                         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw");
3965
3966                         /* Open the binary high score file, for reading */
3967                         highscore_fd = fd_open(buf, O_RDONLY);
3968
3969                         /* Paranoia -- No score file */
3970                         if (highscore_fd < 0)
3971                         {
3972                                 msg_print("Score file unavailable.");
3973                         }
3974                         else
3975                         {
3976                                 screen_save();
3977                                 Term_clear();
3978
3979                                 /* Display the scores */
3980                                 display_scores_aux(0, MAX_HISCORES, -1, NULL);
3981
3982                                 /* Shut the high score file */
3983                                 (void)fd_close(highscore_fd);
3984
3985                                 /* Forget the high score fd */
3986                                 highscore_fd = -1;
3987                                 screen_load();
3988
3989                                 /* Hack - Flush it */
3990                                 Term_fresh();
3991                         }
3992
3993                         break;
3994                 }
3995
3996                 /* Open game */
3997                 case IDM_FILE_MOVIE:
3998                 {
3999                         if (!initialized)
4000                         {
4001                                 plog(_("まだ初期化中です...", "You cannot do that yet..."));
4002                         }
4003                         else if (game_in_progress)
4004                         {
4005                                 plog(_("プレイ中はムービーをロードすることができません!", "You can't open a movie while you're playing!"));
4006                         }
4007                         else
4008                         {
4009                                 memset(&ofn, 0, sizeof(ofn));
4010                                 ofn.lStructSize = sizeof(ofn);
4011                                 ofn.hwndOwner = data[0].w;
4012                                 ofn.lpstrFilter = "Angband Movie Files (*.amv)\0*.amv\0";
4013                                 ofn.nFilterIndex = 1;
4014                                 ofn.lpstrFile = savefile;
4015                                 ofn.nMaxFile = 1024;
4016                                 ofn.lpstrInitialDir = ANGBAND_DIR_USER;
4017                                 ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
4018
4019                                 if (GetOpenFileName(&ofn))
4020                                 {
4021                                         /* Load 'savefile' */
4022                                         prepare_browse_movie_aux(savefile);
4023                                         play_game(FALSE);
4024                                         quit(NULL);
4025                                         return;
4026                                 }
4027                         }
4028                         break;
4029                 }
4030
4031
4032                 case IDM_WINDOW_VIS_0:
4033                 {
4034                         plog(_("メインウィンドウは非表示にできません!", "You are not allowed to do that!"));
4035                         break;
4036                 }
4037
4038                 /* Window visibility */
4039                 case IDM_WINDOW_VIS_1:
4040                 case IDM_WINDOW_VIS_2:
4041                 case IDM_WINDOW_VIS_3:
4042                 case IDM_WINDOW_VIS_4:
4043                 case IDM_WINDOW_VIS_5:
4044                 case IDM_WINDOW_VIS_6:
4045                 case IDM_WINDOW_VIS_7:
4046                 {
4047                         i = wCmd - IDM_WINDOW_VIS_0;
4048
4049                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4050
4051                         td = &data[i];
4052
4053                         if (!td->visible)
4054                         {
4055                                 td->visible = TRUE;
4056                                 ShowWindow(td->w, SW_SHOW);
4057                                 term_data_redraw(td);
4058                         }
4059                         else
4060                         {
4061                                 td->visible = FALSE;
4062                                 td->posfix = FALSE;
4063                                 ShowWindow(td->w, SW_HIDE);
4064                         }
4065
4066                         break;
4067                 }
4068
4069                 /* Window fonts */
4070                 case IDM_WINDOW_FONT_0:
4071                 case IDM_WINDOW_FONT_1:
4072                 case IDM_WINDOW_FONT_2:
4073                 case IDM_WINDOW_FONT_3:
4074                 case IDM_WINDOW_FONT_4:
4075                 case IDM_WINDOW_FONT_5:
4076                 case IDM_WINDOW_FONT_6:
4077                 case IDM_WINDOW_FONT_7:
4078                 {
4079                         i = wCmd - IDM_WINDOW_FONT_0;
4080
4081                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4082
4083                         td = &data[i];
4084
4085                         term_change_font(td);
4086
4087                         break;
4088                 }
4089
4090                 /* Window Z Position */
4091                 case IDM_WINDOW_POS_1:
4092                 case IDM_WINDOW_POS_2:
4093                 case IDM_WINDOW_POS_3:
4094                 case IDM_WINDOW_POS_4:
4095                 case IDM_WINDOW_POS_5:
4096                 case IDM_WINDOW_POS_6:
4097                 case IDM_WINDOW_POS_7:
4098                 {
4099                         i = wCmd - IDM_WINDOW_POS_0;
4100
4101                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4102
4103                         td = &data[i];
4104
4105                         if (!td->posfix && td->visible)
4106                         {
4107                                 td->posfix = TRUE;
4108                                 term_window_pos(td, HWND_TOPMOST);
4109                         }
4110                         else
4111                         {
4112                                 td->posfix = FALSE;
4113                                 term_window_pos(td, data[0].w);
4114                         }
4115
4116                         break;
4117                 }
4118
4119                 /* Bizarre Display */
4120                 case IDM_WINDOW_BIZ_0:
4121                 case IDM_WINDOW_BIZ_1:
4122                 case IDM_WINDOW_BIZ_2:
4123                 case IDM_WINDOW_BIZ_3:
4124                 case IDM_WINDOW_BIZ_4:
4125                 case IDM_WINDOW_BIZ_5:
4126                 case IDM_WINDOW_BIZ_6:
4127                 case IDM_WINDOW_BIZ_7:
4128                 {
4129                         i = wCmd - IDM_WINDOW_BIZ_0;
4130
4131                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4132
4133                         td = &data[i];
4134
4135                         td->bizarre = !td->bizarre;
4136
4137                         term_getsize(td);
4138
4139                         term_window_resize(td);
4140
4141                         break;
4142                 }
4143
4144                 /* Increase Tile Width */
4145                 case IDM_WINDOW_I_WID_0:
4146                 case IDM_WINDOW_I_WID_1:
4147                 case IDM_WINDOW_I_WID_2:
4148                 case IDM_WINDOW_I_WID_3:
4149                 case IDM_WINDOW_I_WID_4:
4150                 case IDM_WINDOW_I_WID_5:
4151                 case IDM_WINDOW_I_WID_6:
4152                 case IDM_WINDOW_I_WID_7:
4153                 {
4154                         i = wCmd - IDM_WINDOW_I_WID_0;
4155
4156                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4157
4158                         td = &data[i];
4159
4160                         td->tile_wid += 1;
4161
4162                         term_getsize(td);
4163
4164                         term_window_resize(td);
4165
4166                         break;
4167                 }
4168
4169                 /* Decrease Tile Height */
4170                 case IDM_WINDOW_D_WID_0:
4171                 case IDM_WINDOW_D_WID_1:
4172                 case IDM_WINDOW_D_WID_2:
4173                 case IDM_WINDOW_D_WID_3:
4174                 case IDM_WINDOW_D_WID_4:
4175                 case IDM_WINDOW_D_WID_5:
4176                 case IDM_WINDOW_D_WID_6:
4177                 case IDM_WINDOW_D_WID_7:
4178                 {
4179                         i = wCmd - IDM_WINDOW_D_WID_0;
4180
4181                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4182
4183                         td = &data[i];
4184
4185                         td->tile_wid -= 1;
4186
4187                         term_getsize(td);
4188
4189                         term_window_resize(td);
4190
4191                         break;
4192                 }
4193
4194                 /* Increase Tile Height */
4195                 case IDM_WINDOW_I_HGT_0:
4196                 case IDM_WINDOW_I_HGT_1:
4197                 case IDM_WINDOW_I_HGT_2:
4198                 case IDM_WINDOW_I_HGT_3:
4199                 case IDM_WINDOW_I_HGT_4:
4200                 case IDM_WINDOW_I_HGT_5:
4201                 case IDM_WINDOW_I_HGT_6:
4202                 case IDM_WINDOW_I_HGT_7:
4203                 {
4204                         i = wCmd - IDM_WINDOW_I_HGT_0;
4205
4206                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4207
4208                         td = &data[i];
4209
4210                         td->tile_hgt += 1;
4211
4212                         term_getsize(td);
4213
4214                         term_window_resize(td);
4215
4216                         break;
4217                 }
4218
4219                 /* Decrease Tile Height */
4220                 case IDM_WINDOW_D_HGT_0:
4221                 case IDM_WINDOW_D_HGT_1:
4222                 case IDM_WINDOW_D_HGT_2:
4223                 case IDM_WINDOW_D_HGT_3:
4224                 case IDM_WINDOW_D_HGT_4:
4225                 case IDM_WINDOW_D_HGT_5:
4226                 case IDM_WINDOW_D_HGT_6:
4227                 case IDM_WINDOW_D_HGT_7:
4228                 {
4229                         i = wCmd - IDM_WINDOW_D_HGT_0;
4230
4231                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
4232
4233                         td = &data[i];
4234
4235                         td->tile_hgt -= 1;
4236
4237                         term_getsize(td);
4238
4239                         term_window_resize(td);
4240
4241                         break;
4242                 }
4243
4244                 case IDM_OPTIONS_NO_GRAPHICS:
4245                 {
4246                         if (!inkey_flag)
4247                         {
4248                                 plog("You may not do that right now.");
4249                                 break;
4250                         }
4251
4252                         if (arg_graphics != GRAPHICS_NONE)
4253                         {
4254                                 arg_graphics = GRAPHICS_NONE;
4255                                 Term_xtra_win_react();
4256                                 Term_key_push(KTRL('R'));
4257                         }
4258
4259                         break;
4260                 }
4261
4262                 case IDM_OPTIONS_OLD_GRAPHICS:
4263                 {
4264                         if (!inkey_flag)
4265                         {
4266                                 plog("You may not do that right now.");
4267                                 break;
4268                         }
4269
4270                         if (arg_graphics != GRAPHICS_ORIGINAL)
4271                         {
4272                                 arg_graphics = GRAPHICS_ORIGINAL;
4273                                 Term_xtra_win_react();
4274                                 Term_key_push(KTRL('R'));
4275                         }
4276
4277                         break;
4278                 }
4279
4280                 case IDM_OPTIONS_NEW_GRAPHICS:
4281                 {
4282                         if (!inkey_flag)
4283                         {
4284                                 plog("You may not do that right now.");
4285                                 break;
4286                         }
4287
4288                         if (arg_graphics != GRAPHICS_ADAM_BOLT)
4289                         {
4290                                 arg_graphics = GRAPHICS_ADAM_BOLT;
4291                                 Term_xtra_win_react();
4292                                 Term_key_push(KTRL('R'));
4293                         }
4294
4295                         break;
4296                 }
4297
4298                 case IDM_OPTIONS_NEW2_GRAPHICS:
4299                 {
4300                         if (!inkey_flag)
4301                         {
4302                                 plog("You may not do that right now.");
4303                                 break;
4304                         }
4305
4306                         if (arg_graphics != GRAPHICS_HENGBAND)
4307                         {
4308                                 arg_graphics = GRAPHICS_HENGBAND;
4309                                 Term_xtra_win_react();
4310                                 Term_key_push(KTRL('R'));
4311                         }
4312
4313                         break;
4314                 }
4315
4316                 case IDM_OPTIONS_BIGTILE:
4317                 {
4318                         td = &data[0];
4319                         if (!inkey_flag)
4320                         {
4321                                 plog("You may not do that right now.");
4322                                 break;
4323                         }
4324
4325                         arg_bigtile = !arg_bigtile;
4326                         Term_activate(&td->t);
4327                         Term_resize(td->cols, td->rows);
4328                         InvalidateRect(td->w, NULL, TRUE);
4329                         break;
4330                 }
4331
4332                 case IDM_OPTIONS_MUSIC:
4333                 {
4334                         if (!inkey_flag)
4335                         {
4336                                 plog("You may not do that right now.");
4337                                 break;
4338                         }
4339
4340                         arg_music = !arg_music;
4341                         Term_xtra_win_react();
4342                         Term_key_push(KTRL('R'));
4343                         break;
4344                 }
4345
4346                 case IDM_OPTIONS_SOUND:
4347                 {
4348                         if (!inkey_flag)
4349                         {
4350                                 plog("You may not do that right now.");
4351                                 break;
4352                         }
4353
4354                         arg_sound = !arg_sound;
4355                         Term_xtra_win_react();
4356                         Term_key_push(KTRL('R'));
4357                         break;
4358                 }
4359
4360                 /* bg */
4361                 case IDM_OPTIONS_BG:
4362                 {
4363                         if (!inkey_flag)
4364                         {
4365                                 plog("You may not do that right now.");
4366                                 break;
4367                         }
4368
4369                         use_bg = !use_bg;
4370                         init_bg();
4371                         Term_xtra_win_react();
4372                         Term_key_push(KTRL('R'));
4373                         break;
4374                 }
4375
4376                 /* bg */
4377                 case IDM_OPTIONS_OPEN_BG:
4378                 {
4379                         if (!inkey_flag)
4380                         {
4381                                 plog("You may not do that right now.");
4382                                 break;
4383                         }
4384                         else
4385                         {
4386                                 memset(&ofn, 0, sizeof(ofn));
4387                                 ofn.lStructSize = sizeof(ofn);
4388                                 ofn.hwndOwner = data[0].w;
4389                                 ofn.lpstrFilter = "Bitmap Files (*.bmp)\0*.bmp\0";
4390                                 ofn.nFilterIndex = 1;
4391                                 ofn.lpstrFile = bg_bitmap_file;
4392                                 ofn.nMaxFile = 1023;
4393                                 ofn.lpstrInitialDir = NULL;
4394                                 ofn.lpstrTitle = _("壁紙を選んでね。", "Choose wall paper.");
4395                                 ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
4396
4397                                 if (GetOpenFileName(&ofn))
4398                                 {
4399                                         /* Load 'savefile' */
4400                                         use_bg = 1;
4401                                         init_bg();
4402                                 }
4403
4404                                 /* React to changes */
4405                                 Term_xtra_win_react();
4406
4407                                 /* Hack -- Force redraw */
4408                                 Term_key_push(KTRL('R'));
4409                         }
4410                         break;
4411                 }
4412
4413                 case IDM_DUMP_SCREEN_HTML:
4414                 {
4415                         static char buf[1024] = "";
4416                         memset(&ofn, 0, sizeof(ofn));
4417                         ofn.lStructSize = sizeof(ofn);
4418                         ofn.hwndOwner = data[0].w;
4419                         ofn.lpstrFilter = "HTML Files (*.html)\0*.html\0";
4420                         ofn.nFilterIndex = 1;
4421                         ofn.lpstrFile = buf;
4422                         ofn.nMaxFile = 1023;
4423                         ofn.lpstrDefExt = "html";
4424                         ofn.lpstrInitialDir = NULL;
4425                         ofn.lpstrTitle = _("HTMLでスクリーンダンプを保存", "Save screen dump as HTML.");
4426                         ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
4427
4428                         if (GetSaveFileName(&ofn))
4429                         {
4430                                 do_cmd_save_screen_html_aux(buf, 0);
4431                         }
4432                         break;
4433                 }
4434
4435 #ifdef USE_SAVER
4436
4437                 case IDM_OPTIONS_SAVER:
4438                 {
4439                         if (hwndSaver)
4440                         {
4441                                 DestroyWindow(hwndSaver);
4442                                 hwndSaver = NULL;
4443                         }
4444                         else
4445                         {
4446                                 /* Create a screen scaver window */
4447                                 hwndSaver = CreateWindowEx(WS_EX_TOPMOST, "WindowsScreenSaverClass",
4448                                                            "Angband Screensaver",
4449                                                            WS_POPUP | WS_MAXIMIZE | WS_VISIBLE,
4450                                                            0, 0, GetSystemMetrics(SM_CXSCREEN),
4451                                                            GetSystemMetrics(SM_CYSCREEN),
4452                                                            NULL, NULL, hInstance, NULL);
4453
4454                                 if (hwndSaver)
4455                                 {
4456                                         /* Push the window to the bottom */
4457                                         SetWindowPos(hwndSaver, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
4458                                 }
4459                                 else
4460                                 {
4461                                         plog(_("ウィンドウを作成出来ません", "Failed to create saver window"));
4462                                 }
4463                         }
4464                         break;
4465                 }
4466
4467 #endif
4468
4469                 case IDM_OPTIONS_MAP:
4470                 {
4471                         windows_map();
4472                         break;
4473                 }
4474
4475                 case IDM_HELP_CONTENTS:
4476                 {
4477 #ifdef HTML_HELP
4478                         char tmp[1024];
4479                         path_build(tmp, sizeof(tmp), ANGBAND_DIR_XTRA_HELP, "zangband.chm");
4480                         if (check_file(tmp))
4481                         {
4482                                 HtmlHelp(data[0].w, tmp, HH_DISPLAY_TOPIC, 0);
4483                         }
4484                         else
4485                         {
4486                                 plog_fmt(_("ヘルプファイル[%s]が見付かりません。", "Cannot find help file: %s"), tmp);
4487                                 plog(_("代わりにオンラインヘルプを使用してください。", "Use the online help files instead."));
4488                         }
4489                         break;
4490 #else /* HTML_HELP */
4491                         char buf[1024];
4492                         char tmp[1024];
4493                         path_build(tmp, sizeof(tmp), ANGBAND_DIR_XTRA_HELP, "zangband.hlp");
4494                         if (check_file(tmp))
4495                         {
4496                                 sprintf(buf, "winhelp.exe %s", tmp);
4497                                 WinExec(buf, SW_NORMAL);
4498                         }
4499                         else
4500                         {
4501                                 plog_fmt(_("ヘルプファイル[%s]が見付かりません。", "Cannot find help file: %s"), tmp);
4502                                 plog(_("代わりにオンラインヘルプを使用してください。", "Use the online help files instead."));
4503
4504                         }
4505                         break;
4506 #endif /* HTML_HELP */
4507                 }
4508         }
4509 }
4510
4511
4512 static bool process_keydown(WPARAM wParam, LPARAM lParam)
4513 {
4514         int i;
4515         bool mc = FALSE;
4516         bool ms = FALSE;
4517         bool ma = FALSE;
4518
4519         /* Extract the modifiers */
4520         if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
4521         if (GetKeyState(VK_SHIFT)   & 0x8000) ms = TRUE;
4522         if (GetKeyState(VK_MENU)    & 0x8000) ma = TRUE;
4523
4524         Term_no_press = (ma) ? TRUE : FALSE;
4525
4526         /* Handle "special" keys */
4527         if (special_key[(byte)(wParam)] || (ma && !ignore_key[(byte)(wParam)]) )
4528         {
4529                 bool ext_key = (lParam & 0x1000000L) ? TRUE : FALSE;
4530                 bool numpad = FALSE;
4531
4532                 /* Begin the macro trigger */
4533                 Term_keypress(31);
4534
4535                 /* Send the modifiers */
4536                 if (mc) Term_keypress('C');
4537                 if (ms) Term_keypress('S');
4538                 if (ma) Term_keypress('A');
4539
4540                 /* Extract "scan code" */
4541                 i = LOBYTE(HIWORD(lParam));
4542
4543                 /* Introduce the scan code */
4544                 Term_keypress('x');
4545
4546                 /* Extended key bit */
4547                 switch (wParam)
4548                 {
4549                         /* Numpad Enter and '/' are extended key */
4550                 case VK_DIVIDE:
4551                         Term_no_press = TRUE;
4552                 case VK_RETURN: /* Enter */
4553                         numpad = ext_key;
4554                         break;
4555                         /* Other extended keys are on full keyboard */
4556                 case VK_NUMPAD0:
4557                 case VK_NUMPAD1:
4558                 case VK_NUMPAD2:
4559                 case VK_NUMPAD3:
4560                 case VK_NUMPAD4:
4561                 case VK_NUMPAD5:
4562                 case VK_NUMPAD6:
4563                 case VK_NUMPAD7:
4564                 case VK_NUMPAD8:
4565                 case VK_NUMPAD9:
4566                 case VK_ADD:
4567                 case VK_MULTIPLY:
4568                 case VK_SUBTRACT:
4569                 case VK_SEPARATOR:
4570                 case VK_DECIMAL:
4571                         Term_no_press = TRUE;
4572                 case VK_CLEAR:
4573                 case VK_HOME:
4574                 case VK_END:
4575                 case VK_PRIOR:  /* Page Up */
4576                 case VK_NEXT:   /* Page Down */
4577                 case VK_INSERT:
4578                 case VK_DELETE:
4579                 case VK_UP:
4580                 case VK_DOWN:
4581                 case VK_LEFT:
4582                 case VK_RIGHT:
4583                         numpad = !ext_key;
4584                 }
4585
4586                 /* Special modifiers for keypad keys */
4587                 if (numpad) Term_keypress('K');
4588
4589                 /* Encode the hexidecimal scan code */
4590                 Term_keypress(hexsym[i/16]);
4591                 Term_keypress(hexsym[i%16]);
4592
4593                 /* End the macro trigger */
4594                 Term_keypress(13);
4595
4596                 return 1;
4597         }
4598
4599         return 0;
4600 }
4601
4602
4603 #ifdef __MWERKS__
4604 LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
4605                                   WPARAM wParam, LPARAM lParam);
4606 LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
4607                                   WPARAM wParam, LPARAM lParam)
4608 #else /* __MWERKS__ */
4609 LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
4610 #endif /* __MWERKS__ */
4611 {
4612         PAINTSTRUCT ps;
4613         HDC hdc;
4614         term_data *td;
4615 #if 0
4616         MINMAXINFO FAR *lpmmi;
4617         RECT rc;
4618 #endif
4619         int i;
4620
4621
4622         /* Acquire proper "term_data" info */
4623         td = (term_data *)GetWindowLong(hWnd, 0);
4624
4625         /* Handle message */
4626         switch (uMsg)
4627         {
4628                 case WM_NCCREATE:
4629                 {
4630                         SetWindowLong(hWnd, 0, (LONG)(my_td));
4631                         break;
4632                 }
4633
4634                 case WM_CREATE:
4635                 {
4636 #ifdef USE_MUSIC
4637                         mop.dwCallback=(DWORD)hWnd;
4638 #endif
4639                         return 0;
4640                 }
4641
4642                 case WM_GETMINMAXINFO:
4643                 {
4644                         MINMAXINFO FAR *lpmmi;
4645                         RECT rc;
4646
4647                         lpmmi = (MINMAXINFO FAR *)lParam;
4648
4649                         /* this message was sent before WM_NCCREATE */
4650                         if (!td) return 1;
4651
4652                         /* Minimum window size is 80x24 */
4653                         rc.left = rc.top = 0;
4654                         rc.right = rc.left + 80 * td->tile_wid + td->size_ow1 + td->size_ow2;
4655                         rc.bottom = rc.top + 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
4656
4657                         /* Adjust */
4658                         AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
4659
4660                         /* Save minimum size */
4661                         lpmmi->ptMinTrackSize.x = rc.right - rc.left;
4662                         lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;
4663
4664                         return 0;
4665                 }
4666
4667                 case WM_PAINT:
4668                 {
4669                         BeginPaint(hWnd, &ps);
4670                         if (td) term_data_redraw(td);
4671                         EndPaint(hWnd, &ps);
4672                         ValidateRect(hWnd, NULL);
4673                         return 0;
4674                 }
4675
4676 #ifdef USE_MUSIC
4677                 case MM_MCINOTIFY:
4678                 {
4679                         if(wParam == MCI_NOTIFY_SUCCESSFUL)
4680                         {
4681                                 mciSendCommand(mop.wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, 0);
4682                                 mciSendCommand(mop.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)&mop);
4683                         }
4684                         return 0;
4685                 }
4686 #endif
4687
4688                 case WM_SYSKEYDOWN:
4689                 case WM_KEYDOWN:
4690                 {
4691                         if (process_keydown(wParam, lParam))
4692                                 return 0;
4693                         break;
4694                 }
4695
4696                 case WM_CHAR:
4697                 {
4698                         if (Term_no_press) Term_no_press = FALSE;
4699                         else Term_keypress(wParam);
4700                         return 0;
4701                 }
4702
4703                 case WM_LBUTTONDOWN:
4704                 {
4705                         mousex = MIN(LOWORD(lParam) / td->tile_wid, td->cols - 1);
4706                         mousey = MIN(HIWORD(lParam) / td->tile_hgt, td->rows - 1);
4707                         mouse_down = TRUE;
4708                         oldx = mousex;
4709                         oldy = mousey;
4710                         return 0;
4711                 }
4712
4713                 case WM_LBUTTONUP:
4714                 {
4715                         HGLOBAL hGlobal;
4716                         LPSTR lpStr;
4717                         int j, sz;
4718                         TERM_LEN dx = abs(oldx - mousex) + 1;
4719                         TERM_LEN dy = abs(oldy - mousey) + 1;
4720                         TERM_LEN ox = (oldx > mousex) ? mousex : oldx;
4721                         TERM_LEN oy = (oldy > mousey) ? mousey : oldy;
4722
4723                         mouse_down = FALSE;
4724                         paint_rect = FALSE;
4725
4726 #ifdef JP
4727                         sz = (dx + 3) * dy;
4728 #else
4729                         sz = (dx + 2) * dy;
4730 #endif
4731                         hGlobal = GlobalAlloc(GHND, sz + 1);
4732                         if (hGlobal == NULL) return 0;
4733                         lpStr = (LPSTR)GlobalLock(hGlobal);
4734
4735                         for (i = 0; i < dy; i++)
4736                         {
4737 #ifdef JP
4738                                 char *s;
4739                                 char **scr = data[0].t.scr->c;
4740
4741                                 C_MAKE(s, (dx + 1), char);
4742                                 strncpy(s, &scr[oy + i][ox], dx);
4743
4744                                 if (ox > 0)
4745                                 {
4746                                         if (iskanji(scr[oy + i][ox - 1])) s[0] = ' ';
4747                                 }
4748
4749                                 if (ox + dx < data[0].cols)
4750                                 {
4751                                         if (iskanji(scr[oy + i][ox + dx - 1])) s[dx - 1] = ' ';
4752                                 }
4753
4754                                 for (j = 0; j < dx; j++)
4755                                 {
4756                                         if (s[j] == 127) s[j] = '#';
4757                                         *lpStr++ = s[j];
4758                                 }
4759 #else
4760                                 for (j = 0; j < dx; j++)
4761                                 {
4762                                         *lpStr++ = data[0].t.scr->c[oy + i][ox + j];
4763                                 }
4764 #endif
4765                                 if (dy > 1)
4766                                 {
4767                                         *lpStr++ = '\r';
4768                                         *lpStr++ = '\n';
4769                                 }
4770                         }
4771
4772                         GlobalUnlock(hGlobal);
4773                         if (OpenClipboard(hWnd) == 0)
4774                         {
4775                                 GlobalFree(hGlobal);
4776                                 return 0;
4777                         }
4778                         EmptyClipboard();
4779                         SetClipboardData(CF_TEXT, hGlobal);
4780                         CloseClipboard();
4781
4782                         Term_redraw();
4783
4784                         return 0;
4785                 }
4786
4787                 case WM_MOUSEMOVE:
4788                 {
4789                         if (mouse_down)
4790                         {
4791                                 int dx, dy;
4792                                 int cx = MIN(LOWORD(lParam) / td->tile_wid, td->cols - 1);
4793                                 int cy = MIN(HIWORD(lParam) / td->tile_hgt, td->rows - 1);
4794                                 int ox, oy;
4795
4796                                 if (paint_rect)
4797                                 {
4798                                         dx = abs(oldx - mousex) + 1;
4799                                         dy = abs(oldy - mousey) + 1;
4800                                         ox = (oldx > mousex) ? mousex : oldx;
4801                                         oy = (oldy > mousey) ? mousey : oldy;
4802                                         Term_inversed_area(hWnd, ox, oy, dx, dy);
4803                                 }
4804                                 else
4805                                 {
4806                                         paint_rect = TRUE;
4807                                 }
4808
4809                                 dx = abs(cx - mousex) + 1;
4810                                 dy = abs(cy - mousey) + 1;
4811                                 ox = (cx > mousex) ? mousex : cx;
4812                                 oy = (cy > mousey) ? mousey : cy;
4813                                 Term_inversed_area(hWnd, ox, oy, dx, dy);
4814
4815                                 oldx = cx;
4816                                 oldy = cy;
4817                         }
4818                         return 0;
4819                 }
4820
4821                 case WM_INITMENU:
4822                 {
4823                         setup_menus();
4824                         return 0;
4825                 }
4826
4827                 case WM_CLOSE:
4828                 {
4829                         if (game_in_progress && current_world_ptr->character_generated)
4830                         {
4831                                 if (!can_save)
4832                                 {
4833                                         plog(_("今は終了できません。", "You may not do that right now."));
4834                                         return 0;
4835                                 }
4836
4837                                 /* Hack -- Forget messages */
4838                                 msg_flag = FALSE;
4839
4840                                 forget_lite();
4841                                 forget_view();
4842                                 clear_mon_lite();
4843
4844                                 /* Save the game */
4845 #ifdef ZANGBAND
4846                                 /* do_cmd_save_game(FALSE); */
4847 #else /* ZANGBAND */
4848                                 /* do_cmd_save_game(); */
4849 #endif /* ZANGBAND */
4850                                 Term_key_push(SPECIAL_KEY_QUIT);
4851                                 return 0;
4852                         }
4853                         quit(NULL);
4854                         return 0;
4855                 }
4856
4857                 case WM_QUERYENDSESSION:
4858                 {
4859                         if (game_in_progress && current_world_ptr->character_generated)
4860                         {
4861                                 /* Hack -- Forget messages */
4862                                 msg_flag = FALSE;
4863
4864                                 /* Mega-Hack -- Delay death */
4865                                 if (p_ptr->chp < 0) p_ptr->is_dead = FALSE;
4866                                 do_cmd_write_nikki(p_ptr, NIKKI_GAMESTART, 0, _("----ゲーム中断----", "---- Save and Exit Game ----"));
4867
4868                                 /* Hardcode panic save */
4869                                 p_ptr->panic_save = 1;
4870
4871                                 /* Forbid suspend */
4872                                 signals_ignore_tstp();
4873
4874                                 /* Indicate panic save */
4875                                 (void)strcpy(p_ptr->died_from, _("(緊急セーブ)", "(panic save)"));
4876
4877                                 /* Panic save */
4878                                 (void)save_player();
4879                         }
4880                         quit(NULL);
4881                         return 0;
4882                 }
4883
4884                 case WM_QUIT:
4885                 {
4886                         quit(NULL);
4887                         return 0;
4888                 }
4889
4890                 case WM_COMMAND:
4891                 {
4892                         process_menus(LOWORD(wParam));
4893                         return 0;
4894                 }
4895
4896                 case WM_SIZE:
4897                 {
4898                         /* this message was sent before WM_NCCREATE */
4899                         if (!td) return 1;
4900
4901                         /* it was sent from inside CreateWindowEx */
4902                         if (!td->w) return 1;
4903
4904                         /* was sent from WM_SIZE */
4905                         if (td->size_hack) return 1;
4906
4907                         switch (wParam)
4908                         {
4909                                 case SIZE_MINIMIZED:
4910                                 {
4911                                         /* Hide sub-windows */
4912                                         for (i = 1; i < MAX_TERM_DATA; i++)
4913                                         {
4914                                                 if (data[i].visible) ShowWindow(data[i].w, SW_HIDE);
4915                                         }
4916                                         return 0;
4917                                 }
4918
4919                                 case SIZE_MAXIMIZED:
4920                                 {
4921                                         /* fall through */
4922                                 }
4923
4924                                 case SIZE_RESTORED:
4925                                 {
4926                                         TERM_LEN cols = (LOWORD(lParam) - td->size_ow1) / td->tile_wid;
4927                                         TERM_LEN rows = (HIWORD(lParam) - td->size_oh1) / td->tile_hgt;
4928
4929                                         /* New size */
4930                                         if ((td->cols != cols) || (td->rows != rows))
4931                                         {
4932                                                 /* Save the new size */
4933                                                 td->cols = cols;
4934                                                 td->rows = rows;
4935
4936                                                 if (!IsZoomed(td->w) && !IsIconic(td->w))
4937                                                 {
4938                                                         normsize.x = td->cols;
4939                                                         normsize.y = td->rows;
4940                                                 }
4941
4942                                                 /* Activate */
4943                                                 Term_activate(&td->t);
4944
4945                                                 /* Resize the term */
4946                                                 Term_resize(td->cols, td->rows);
4947
4948                                                 /* Redraw later */
4949                                                 InvalidateRect(td->w, NULL, TRUE);
4950                                         }
4951
4952                                         td->size_hack = TRUE;
4953
4954                                         /* Show sub-windows */
4955                                         for (i = 1; i < MAX_TERM_DATA; i++)
4956                                         {
4957                                                 if (data[i].visible) ShowWindow(data[i].w, SW_SHOW);
4958                                         }
4959
4960                                         td->size_hack = FALSE;
4961
4962                                         return 0;
4963                                 }
4964                         }
4965                         break;
4966                 }
4967
4968                 case WM_PALETTECHANGED:
4969                 {
4970                         /* Ignore if palette change caused by itself */
4971                         if ((HWND)wParam == hWnd) return 0;
4972
4973                         /* Fall through... */
4974                 }
4975
4976                 case WM_QUERYNEWPALETTE:
4977                 {
4978                         if (!paletted) return 0;
4979
4980                         hdc = GetDC(hWnd);
4981
4982                         SelectPalette(hdc, hPal, FALSE);
4983
4984                         i = RealizePalette(hdc);
4985
4986                         /* if any palette entries changed, repaint the window. */
4987                         if (i) InvalidateRect(hWnd, NULL, TRUE);
4988
4989                         ReleaseDC(hWnd, hdc);
4990
4991                         return 0;
4992                 }
4993
4994                 case WM_ACTIVATE:
4995                 {
4996                         if (wParam && !HIWORD(lParam))
4997                         {
4998                                 /* Do something to sub-windows */
4999                                 for (i = 1; i < MAX_TERM_DATA; i++)
5000                                 {
5001                                         if (!data[i].posfix) term_window_pos(&data[i], hWnd);
5002                                 }
5003
5004                                 /* Focus on main window */
5005                                 SetFocus(hWnd);
5006
5007                                 return 0;
5008                         }
5009
5010                         break;
5011                 }
5012
5013                 case WM_ACTIVATEAPP:
5014                 {
5015                         if (IsIconic(td->w)) break;
5016
5017                         for (i = 1; i < MAX_TERM_DATA; i++)
5018                         {
5019                                 if(data[i].visible)
5020                                 {
5021                                         if (wParam == TRUE)
5022                                         {
5023                                                 ShowWindow(data[i].w, SW_SHOW);
5024                                         }
5025                                         else
5026                                         {
5027                                                 ShowWindow(data[i].w, SW_HIDE);
5028                                         }
5029                                 }
5030                         }
5031                 }
5032         }
5033
5034         return DefWindowProc(hWnd, uMsg, wParam, lParam);
5035 }
5036
5037
5038 #ifdef __MWERKS__
5039 LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
5040                                            WPARAM wParam, LPARAM lParam);
5041 LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
5042                                            WPARAM wParam, LPARAM lParam)
5043 #else /* __MWERKS__ */
5044 LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
5045                                            WPARAM wParam, LPARAM lParam)
5046 #endif /* __MWERKS__ */
5047 {
5048         term_data *td;
5049 #if 0
5050         MINMAXINFO FAR *lpmmi;
5051         RECT rc;
5052 #endif
5053         PAINTSTRUCT ps;
5054         HDC hdc;
5055         int i;
5056
5057
5058         /* Acquire proper "term_data" info */
5059         td = (term_data *)GetWindowLong(hWnd, 0);
5060
5061         /* Process message */
5062         switch (uMsg)
5063         {
5064                 case WM_NCCREATE:
5065                 {
5066                         SetWindowLong(hWnd, 0, (LONG)(my_td));
5067                         break;
5068                 }
5069
5070                 case WM_CREATE:
5071                 {
5072                         return 0;
5073                 }
5074
5075                 case WM_GETMINMAXINFO:
5076                 {
5077                         MINMAXINFO FAR *lpmmi;
5078                         RECT rc;
5079
5080                         lpmmi = (MINMAXINFO FAR *)lParam;
5081
5082                         /* this message was sent before WM_NCCREATE */
5083                         if (!td) return 1;
5084
5085                         /* Minimum window size is 80x24 */
5086                         rc.left = rc.top = 0;
5087                         rc.right = rc.left + 20 * td->tile_wid + td->size_ow1 + td->size_ow2;
5088                         rc.bottom = rc.top + 3 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
5089
5090                         /* Adjust */
5091                         AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
5092
5093                         /* Save minimum size */
5094                         lpmmi->ptMinTrackSize.x = rc.right - rc.left;
5095                         lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;
5096
5097                         return 0;
5098                 }
5099
5100                 case WM_SIZE:
5101                 {
5102                         TERM_LEN cols;
5103                         TERM_LEN rows;
5104                         
5105                         /* this message was sent before WM_NCCREATE */
5106                         if (!td) return 1;
5107
5108                         /* it was sent from inside CreateWindowEx */
5109                         if (!td->w) return 1;
5110
5111                         /* was sent from inside WM_SIZE */
5112                         if (td->size_hack) return 1;
5113
5114                         td->size_hack = TRUE;
5115
5116                         cols = (LOWORD(lParam) - td->size_ow1) / td->tile_wid;
5117                         rows = (HIWORD(lParam) - td->size_oh1) / td->tile_hgt;
5118
5119                         /* New size */
5120                         if ((td->cols != cols) || (td->rows != rows))
5121                         {
5122                                 /* Save old term */
5123                                 term *old_term = Term;
5124
5125                                 /* Save the new size */
5126                                 td->cols = cols;
5127                                 td->rows = rows;
5128
5129                                 /* Activate */
5130                                 Term_activate(&td->t);
5131
5132                                 /* Resize the term */
5133                                 Term_resize(td->cols, td->rows);
5134
5135                                 /* Activate */
5136                                 Term_activate(old_term);
5137
5138                                 /* Redraw later */
5139                                 InvalidateRect(td->w, NULL, TRUE);
5140
5141                                 /* HACK - Redraw all windows */
5142                                 p_ptr->window = 0xFFFFFFFF;
5143                                 handle_stuff();
5144                         }
5145
5146                         td->size_hack = FALSE;
5147
5148                         return 0;
5149                 }
5150
5151                 case WM_PAINT:
5152                 {
5153                         BeginPaint(hWnd, &ps);
5154                         if (td) term_data_redraw(td);
5155                         EndPaint(hWnd, &ps);
5156                         return 0;
5157                 }
5158
5159                 case WM_SYSKEYDOWN:
5160                 case WM_KEYDOWN:
5161                 {
5162                         if (process_keydown(wParam, lParam))
5163                                 return 0;
5164                         break;
5165                 }
5166
5167                 case WM_CHAR:
5168                 {
5169                         if (Term_no_press) Term_no_press = FALSE;
5170                         else Term_keypress(wParam);
5171                         return 0;
5172                 }
5173
5174                 case WM_PALETTECHANGED:
5175                 {
5176                         /* ignore if palette change caused by itself */
5177                         if ((HWND)wParam == hWnd) return FALSE;
5178                         /* otherwise, fall through!!! */
5179                 }
5180
5181                 case WM_QUERYNEWPALETTE:
5182                 {
5183                         if (!paletted) return 0;
5184                         hdc = GetDC(hWnd);
5185                         SelectPalette(hdc, hPal, FALSE);
5186                         i = RealizePalette(hdc);
5187                         /* if any palette entries changed, repaint the window. */
5188                         if (i) InvalidateRect(hWnd, NULL, TRUE);
5189                         ReleaseDC(hWnd, hdc);
5190                         return 0;
5191                 }
5192
5193                 case WM_NCLBUTTONDOWN:
5194                 {
5195
5196 #ifdef HTCLOSE
5197                         if (wParam == HTCLOSE) wParam = HTSYSMENU;
5198 #endif /* HTCLOSE */
5199
5200                         if (wParam == HTSYSMENU)
5201                         {
5202                                 if (td->visible)
5203                                 {
5204                                         td->visible = FALSE;
5205                                         ShowWindow(td->w, SW_HIDE);
5206                                 }
5207
5208                                 return 0;
5209                         }
5210
5211                         break;
5212                 }
5213         }
5214
5215         return DefWindowProc(hWnd, uMsg, wParam, lParam);
5216 }
5217
5218
5219 #ifdef USE_SAVER
5220
5221 #define MOUSE_SENS 40
5222
5223 #ifdef __MWERKS__
5224 LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
5225                                     WPARAM wParam, LPARAM lParam);
5226 LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
5227                                     WPARAM wParam, LPARAM lParam)
5228 #else /* __MWERKS__ */
5229 LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
5230                                             WPARAM wParam, LPARAM lParam)
5231 #endif /* __MWERKS__ */
5232 {
5233         static int iMouse = 0;
5234         static WORD xMouse = 0;
5235         static WORD yMouse = 0;
5236
5237         int dx, dy;
5238
5239
5240         /* Process */
5241         switch (uMsg)
5242         {
5243                 case WM_NCCREATE:
5244                 {
5245                         break;
5246                 }
5247
5248                 case WM_SETCURSOR:
5249                 {
5250                         SetCursor(NULL);
5251                         return 0;
5252                 }
5253
5254 #if 0
5255                 case WM_ACTIVATE:
5256                 {
5257                         if (LOWORD(wParam) == WA_INACTIVE) break;
5258
5259                         /* else fall through */
5260                 }
5261 #endif
5262
5263                 case WM_LBUTTONDOWN:
5264                 case WM_MBUTTONDOWN:
5265                 case WM_RBUTTONDOWN:
5266                 case WM_KEYDOWN:
5267                 {
5268                         SendMessage(hWnd, WM_CLOSE, 0, 0);
5269                         return 0;
5270                 }
5271
5272                 case WM_MOUSEMOVE:
5273                 {
5274                         if (iMouse)
5275                         {
5276                                 dx = LOWORD(lParam) - xMouse;
5277                                 dy = HIWORD(lParam) - yMouse;
5278
5279                                 if (dx < 0) dx = -dx;
5280                                 if (dy < 0) dy = -dy;
5281
5282                                 if ((dx > MOUSE_SENS) || (dy > MOUSE_SENS))
5283                                 {
5284                                         SendMessage(hWnd, WM_CLOSE, 0, 0);
5285                                 }
5286                         }
5287
5288                         /* Save last location */
5289                         iMouse = 1;
5290                         xMouse = LOWORD(lParam);
5291                         yMouse = HIWORD(lParam);
5292
5293                         return 0;
5294                 }
5295
5296                 case WM_CLOSE:
5297                 {
5298                         DestroyWindow(hwndSaver);
5299                         hwndSaver = NULL;
5300                         return 0;
5301                 }
5302         }
5303
5304         return DefWindowProc(hWnd, uMsg, wParam, lParam);
5305 }
5306
5307 #endif /* USE_SAVER */
5308
5309
5310
5311
5312
5313 /*** Temporary Hooks ***/
5314
5315
5316 /*
5317  * Display warning message (see "z-util.c")
5318  */
5319 static void hack_plog(concptr str)
5320 {
5321         /* Give a warning */
5322         if (str)
5323         {
5324 #ifdef JP
5325                 MessageBox(NULL, str, "警告!",
5326                            MB_ICONEXCLAMATION | MB_OK);
5327 #else
5328                 MessageBox(NULL, str, "Warning",
5329                            MB_ICONEXCLAMATION | MB_OK);
5330 #endif
5331
5332         }
5333 }
5334
5335
5336 /*
5337  * Display error message and quit (see "z-util.c")
5338  */
5339 static void hack_quit(concptr str)
5340 {
5341         /* Give a warning */
5342         if (str)
5343         {
5344 #ifdef JP
5345                 MessageBox(NULL, str, "エラー!",
5346                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
5347 #else
5348                 MessageBox(NULL, str, "Error",
5349                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
5350 #endif
5351
5352         }
5353
5354         /* Unregister the classes */
5355         UnregisterClass(AppName, hInstance);
5356
5357         /* Destroy the icon */
5358         if (hIcon) DestroyIcon(hIcon);
5359
5360         exit(0);
5361 }
5362
5363
5364
5365 /*** Various hooks ***/
5366
5367
5368 /*
5369  * Display warning message (see "z-util.c")
5370  */
5371 static void hook_plog(concptr str)
5372 {
5373         /* Warning */
5374         if (str)
5375         {
5376 #ifdef JP
5377                 MessageBox(data[0].w, str, "警告!",
5378                            MB_ICONEXCLAMATION | MB_OK);
5379 #else
5380                 MessageBox(data[0].w, str, "Warning",
5381                            MB_ICONEXCLAMATION | MB_OK);
5382 #endif
5383
5384         }
5385 }
5386
5387
5388 /*
5389  * Display error message and quit (see "z-util.c")
5390  */
5391 static void hook_quit(concptr str)
5392 {
5393         int i;
5394
5395
5396         /* Give a warning */
5397         if (str)
5398         {
5399 #ifdef JP
5400                 MessageBox(data[0].w, str, "エラー!",
5401                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
5402 #else
5403                 MessageBox(data[0].w, str, "Error",
5404                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
5405 #endif
5406
5407         }
5408
5409
5410         /* Save the preferences */
5411         save_prefs();
5412
5413
5414         /*** Could use 'Term_nuke_win()' */
5415
5416         /* Destroy all windows */
5417         for (i = MAX_TERM_DATA - 1; i >= 0; --i)
5418         {
5419                 term_force_font(&data[i], NULL);
5420                 if (data[i].font_want) string_free(data[i].font_want);
5421                 if (data[i].w) DestroyWindow(data[i].w);
5422                 data[i].w = 0;
5423         }
5424
5425         /* Free the bitmap stuff */
5426 #ifdef USE_GRAPHICS
5427         if (infGraph.hPalette) DeleteObject(infGraph.hPalette);
5428         if (infGraph.hBitmap) DeleteObject(infGraph.hBitmap);
5429
5430         if (infMask.hPalette) DeleteObject(infMask.hPalette);
5431         if (infMask.hBitmap) DeleteObject(infMask.hBitmap);
5432
5433 #endif /* USE_GRAPHICS */
5434
5435         /*** Free some other stuff ***/
5436
5437         DeleteObject(hbrYellow);
5438
5439         /* bg */
5440         delete_bg();
5441
5442         if (hPal) DeleteObject(hPal);
5443
5444         UnregisterClass(AppName, hInstance);
5445
5446         if (hIcon) DestroyIcon(hIcon);
5447
5448         exit(0);
5449 }
5450
5451
5452
5453 /*** Initialize ***/
5454
5455
5456 /*
5457  * Init some stuff
5458  */
5459 static void init_stuff(void)
5460 {
5461         int i;
5462
5463         char path[1024];
5464
5465
5466         /* Get program name with full path */
5467         GetModuleFileName(hInstance, path, 512);
5468
5469         /* Save the "program name" */
5470         argv0 = path;
5471
5472         /* Get the name of the "*.ini" file */
5473         strcpy(path + strlen(path) - 4, ".INI");
5474
5475         /* Save the the name of the ini-file */
5476         ini_file = string_make(path);
5477
5478         /* Analyze the path */
5479         i = strlen(path);
5480
5481         /* Get the path */
5482         for (; i > 0; i--)
5483         {
5484                 if (path[i] == '\\')
5485                 {
5486                         /* End of path */
5487                         break;
5488                 }
5489         }
5490
5491         /* Add "lib" to the path */
5492         strcpy(path + i + 1, "lib\\");
5493
5494         /* Validate the path */
5495         validate_dir(path, TRUE);
5496
5497         /* Init the file paths */
5498         init_file_paths(path);
5499
5500         /* Hack -- Validate the paths */
5501         validate_dir(ANGBAND_DIR_APEX, FALSE);
5502         validate_dir(ANGBAND_DIR_BONE, FALSE);
5503
5504         /* Allow missing 'edit' directory */
5505         if (!check_dir(ANGBAND_DIR_EDIT))
5506         {
5507                 /* Must have 'data'! */
5508                 validate_dir(ANGBAND_DIR_DATA, TRUE);
5509         }
5510         else
5511         {
5512                 /* Don't need 'data' */
5513                 validate_dir(ANGBAND_DIR_DATA, FALSE);
5514         }
5515
5516         validate_dir(ANGBAND_DIR_FILE, TRUE);
5517         validate_dir(ANGBAND_DIR_HELP, FALSE);
5518         validate_dir(ANGBAND_DIR_INFO, FALSE);
5519         validate_dir(ANGBAND_DIR_PREF, TRUE);
5520         validate_dir(ANGBAND_DIR_SAVE, FALSE);
5521         validate_dir(ANGBAND_DIR_USER, TRUE);
5522         validate_dir(ANGBAND_DIR_XTRA, TRUE);
5523         path_build(path, sizeof(path), ANGBAND_DIR_FILE, _("news_j.txt", "news.txt"));
5524
5525         /* Hack -- Validate the "news.txt" file */
5526         validate_file(path);
5527
5528
5529 #if 0 /* #ifndef JP */
5530         /* Build the "font" path */
5531         path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "font");
5532
5533         /* Allocate the path */
5534         ANGBAND_DIR_XTRA_FONT = string_make(path);
5535
5536         /* Validate the "font" directory */
5537         validate_dir(ANGBAND_DIR_XTRA_FONT, TRUE);
5538         path_build(path, sizeof(path), ANGBAND_DIR_XTRA_FONT, "8X13.FON");
5539
5540         /* Hack -- Validate the basic font */
5541         validate_file(path);
5542 #endif
5543
5544
5545 #ifdef USE_GRAPHICS
5546
5547         /* Build the "graf" path */
5548         path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "graf");
5549
5550         /* Allocate the path */
5551         ANGBAND_DIR_XTRA_GRAF = string_make(path);
5552
5553         /* Validate the "graf" directory */
5554         validate_dir(ANGBAND_DIR_XTRA_GRAF, TRUE);
5555
5556 #endif /* USE_GRAPHICS */
5557
5558
5559 #ifdef USE_SOUND
5560
5561         /* Build the "sound" path */
5562         path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "sound");
5563
5564         /* Allocate the path */
5565         ANGBAND_DIR_XTRA_SOUND = string_make(path);
5566
5567         /* Validate the "sound" directory */
5568         validate_dir(ANGBAND_DIR_XTRA_SOUND, FALSE);
5569
5570 #endif /* USE_SOUND */
5571
5572 #ifdef USE_MUSIC
5573
5574         /* Build the "music" path */
5575         path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "music");
5576
5577         /* Allocate the path */
5578         ANGBAND_DIR_XTRA_MUSIC = string_make(path);
5579
5580         /* Validate the "music" directory */
5581         validate_dir(ANGBAND_DIR_XTRA_MUSIC, FALSE);
5582
5583 #endif /* USE_MUSIC */
5584
5585         /* Build the "help" path */
5586         path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "help");
5587
5588         /* Allocate the path */
5589         ANGBAND_DIR_XTRA_HELP = string_make(path);
5590
5591         /* Validate the "help" directory */
5592         /* validate_dir(ANGBAND_DIR_XTRA_HELP); */
5593 }
5594
5595 /*!
5596  * @brief (Windows固有)変愚蛮怒が起動済かどうかのチェック
5597  */
5598 static bool is_already_running(void)
5599 {
5600         bool result = FALSE;
5601         HANDLE hMutex;
5602
5603         hMutex = CreateMutex(NULL, TRUE, VERSION_NAME);
5604         if (GetLastError() == ERROR_ALREADY_EXISTS)
5605         {
5606                 result = TRUE;
5607         }
5608         return result;
5609 }
5610
5611
5612 /*!
5613  * @brief (Windows固有)Windowsアプリケーションとしてのエントリポイント
5614  */
5615 int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
5616                        LPSTR lpCmdLine, int nCmdShow)
5617 {
5618         int i;
5619
5620         WNDCLASS wc;
5621         HDC hdc;
5622         MSG msg;
5623
5624         setlocale(LC_ALL, "ja_JP.utf8");
5625
5626         /* Unused */
5627         (void)nCmdShow;
5628
5629         /* Save globally */
5630         hInstance = hInst;
5631         
5632         
5633         /* Prevent multiple run */
5634         if (is_already_running())
5635         {
5636                 MessageBox(NULL,
5637                                 _("変愚蛮怒はすでに起動しています。", "Hengband is already running."), 
5638                                 _("エラー!", "Error") ,
5639                                 MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
5640                 return FALSE;
5641         }
5642
5643         if (hPrevInst == NULL)
5644         {
5645                 wc.style         = CS_CLASSDC;
5646                 wc.lpfnWndProc   = AngbandWndProc;
5647                 wc.cbClsExtra    = 0;
5648                 wc.cbWndExtra    = 4; /* one long pointer to term_data */
5649                 wc.hInstance     = hInst;
5650                 wc.hIcon         = hIcon = LoadIcon(hInst, AppName);
5651                 wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
5652                 wc.hbrBackground = GetStockObject(BLACK_BRUSH);
5653                 wc.lpszMenuName  = AppName;
5654                 wc.lpszClassName = AppName;
5655
5656                 if (!RegisterClass(&wc)) exit(1);
5657
5658                 wc.lpfnWndProc   = AngbandListProc;
5659                 wc.lpszMenuName  = NULL;
5660                 wc.lpszClassName = AngList;
5661
5662                 if (!RegisterClass(&wc)) exit(2);
5663
5664 #ifdef USE_SAVER
5665
5666                 wc.style          = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_DBLCLKS;
5667                 wc.lpfnWndProc    = AngbandSaverProc;
5668                 wc.hCursor        = NULL;
5669                 wc.lpszMenuName   = NULL;
5670                 wc.lpszClassName  = "WindowsScreenSaverClass";
5671
5672                 if (!RegisterClass(&wc)) exit(3);
5673
5674 #endif
5675
5676         }
5677
5678         /* Temporary hooks */
5679         plog_aux = hack_plog;
5680         quit_aux = hack_quit;
5681         core_aux = hack_quit;
5682
5683         /* Prepare the filepaths */
5684         init_stuff();
5685
5686         /* Initialize the keypress analyzer */
5687         for (i = 0; special_key_list[i]; ++i)
5688         {
5689                 special_key[special_key_list[i]] = TRUE;
5690         }
5691         /* Initialize the keypress analyzer */
5692         for (i = 0; ignore_key_list[i]; ++i)
5693         {
5694                 ignore_key[ignore_key_list[i]] = TRUE;
5695         }
5696
5697         /* Determine if display is 16/256/true color */
5698         hdc = GetDC(NULL);
5699         colors16 = (GetDeviceCaps(hdc, BITSPIXEL) == 4);
5700         paletted = ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? TRUE : FALSE);
5701         ReleaseDC(NULL, hdc);
5702
5703         /* Initialize the colors */
5704         for (i = 0; i < 256; i++)
5705         {
5706                 byte rv, gv, bv;
5707
5708                 /* Extract desired values */
5709                 rv = angband_color_table[i][1];
5710                 gv = angband_color_table[i][2];
5711                 bv = angband_color_table[i][3];
5712
5713                 /* Extract the "complex" code */
5714                 win_clr[i] = PALETTERGB(rv, gv, bv);
5715
5716                 /* Save the "simple" code */
5717                 angband_color_table[i][0] = win_pal[i];
5718         }
5719
5720         /* Prepare the windows */
5721         init_windows();
5722
5723         /* bg */
5724         init_bg();
5725
5726         /* Activate hooks */
5727         plog_aux = hook_plog;
5728         quit_aux = hook_quit;
5729         core_aux = hook_quit;
5730
5731         /* Set the system suffix */
5732         ANGBAND_SYS = "win";
5733
5734         /* Set the keyboard suffix */
5735         if (7 != GetKeyboardType(0))
5736                 ANGBAND_KEYBOARD = "0";
5737         else
5738         {
5739                 /* Japanese keyboard */
5740                 switch (GetKeyboardType(1))
5741                 {
5742                 case 0x0D01: case 0x0D02:
5743                 case 0x0D03: case 0x0D04:
5744                 case 0x0D05: case 0x0D06:
5745                         /* NEC PC-98x1 */
5746                         ANGBAND_KEYBOARD = "NEC98";
5747                         break;
5748                 default:
5749                         /* PC/AT */
5750                         ANGBAND_KEYBOARD = "JAPAN";
5751                 }
5752         }
5753
5754         /* Catch nasty signals */
5755         signals_init();
5756
5757         Term_activate(term_screen);
5758         init_angband();
5759
5760         /* We are now initialized */
5761         initialized = TRUE;
5762 #ifdef CHUUKEI
5763         if(lpCmdLine[0] == '-'){
5764           switch(lpCmdLine[1])
5765           {
5766           case 'p':
5767           case 'P':
5768             {
5769               if (!lpCmdLine[2]) break;
5770               chuukei_server = TRUE;
5771               if(connect_chuukei_server(&lpCmdLine[2])<0){
5772                 msg_print("connect fail");
5773                 return 0;
5774               }
5775               msg_print("connect");
5776               msg_print(NULL);
5777               break;
5778             }
5779
5780           case 'c':
5781           case 'C':
5782             {
5783               if (!lpCmdLine[2]) break;
5784               chuukei_client = TRUE;
5785               connect_chuukei_server(&lpCmdLine[2]);
5786               play_game(FALSE);
5787               quit(NULL);
5788               return 0;
5789             }
5790           case 'X':
5791           case 'x':
5792             {
5793               if (!lpCmdLine[2]) break;
5794               prepare_browse_movie(&lpCmdLine[2]);
5795               play_game(FALSE);
5796               quit(NULL);
5797               return 0;
5798             }
5799           }
5800         }
5801 #endif
5802
5803 #ifdef CHUUKEI
5804         /* Did the user double click on a save file? */
5805         if(!chuukei_server) check_for_save_file(lpCmdLine);
5806 #else
5807         /* Did the user double click on a save file? */
5808         check_for_save_file(lpCmdLine);
5809 #endif
5810
5811         /* Prompt the user */
5812         prt(_("[ファイル] メニューの [新規] または [開く] を選択してください。", "[Choose 'New' or 'Open' from the 'File' menu]"), 23, _(8, 17));
5813
5814         Term_fresh();
5815
5816         /* Process messages forever */
5817         while (GetMessage(&msg, NULL, 0, 0))
5818         {
5819                 TranslateMessage(&msg);
5820                 DispatchMessage(&msg);
5821         }
5822         quit(NULL);
5823         return (0);
5824 }
5825
5826
5827 #endif /* WINDOWS */
5828