OSDN Git Service

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