OSDN Git Service

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