OSDN Git Service

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