OSDN Git Service

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