OSDN Git Service

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