OSDN Git Service

068d886cfa978eddd4767c3f47a012e1a31ec8b0
[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         uint rows;      /* int -> uint */
363         uint 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 #if 0
1003         /* Paranoia */
1004         if (td->cols > 80) td->cols = 80;
1005         if (td->rows > 24) td->rows = 24;
1006 #endif
1007
1008         /* Window sizes */
1009         wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
1010         hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
1011
1012         /* Fake window size */
1013         rc.left = 0;
1014         rc.right = rc.left + wid;
1015         rc.top = 0;
1016         rc.bottom = rc.top + hgt;
1017
1018         /* XXX XXX XXX */
1019         /* rc.right += 1; */
1020         /* rc.bottom += 1; */
1021
1022         /* Adjust */
1023         AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
1024
1025         /* Total size */
1026         td->size_wid = rc.right - rc.left;
1027         td->size_hgt = rc.bottom - rc.top;
1028
1029         /* See CreateWindowEx */
1030         if (!td->w) return;
1031
1032         /* Extract actual location */
1033         GetWindowRect(td->w, &rc);
1034
1035         /* Save the location */
1036         td->pos_x = rc.left;
1037         td->pos_y = rc.top;
1038 }
1039
1040
1041 /*
1042  * Write the "prefs" for a single term
1043  */
1044 static void save_prefs_aux(term_data *td, cptr sec_name)
1045 {
1046         char buf[1024];
1047
1048         RECT rc;
1049
1050         /* Paranoia */
1051         if (!td->w) return;
1052
1053         /* Visible */
1054         strcpy(buf, td->visible ? "1" : "0");
1055         WritePrivateProfileString(sec_name, "Visible", buf, ini_file);
1056
1057         /* Font */
1058 #ifdef JP
1059         strcpy(buf, td->lf.lfFaceName[0]!='\0' ? td->lf.lfFaceName : "£Í£Ó ¥´¥·¥Ã¥¯");
1060 #else
1061         strcpy(buf, td->font_file ? td->font_file : "8X13.FON");
1062 #endif
1063
1064         WritePrivateProfileString(sec_name, "Font", buf, ini_file);
1065
1066 #ifdef JP
1067         wsprintf(buf, "%d", td->lf.lfWidth);
1068         WritePrivateProfileString(sec_name, "FontWid", buf, ini_file);
1069         wsprintf(buf, "%d", td->lf.lfHeight);
1070         WritePrivateProfileString(sec_name, "FontHgt", buf, ini_file);
1071         wsprintf(buf, "%d", td->lf.lfWeight);
1072         WritePrivateProfileString(sec_name, "FontWgt", buf, ini_file);
1073 #endif
1074         /* Bizarre */
1075         strcpy(buf, td->bizarre ? "1" : "0");
1076         WritePrivateProfileString(sec_name, "Bizarre", buf, ini_file);
1077
1078         /* Tile size (x) */
1079         wsprintf(buf, "%d", td->tile_wid);
1080         WritePrivateProfileString(sec_name, "TileWid", buf, ini_file);
1081
1082         /* Tile size (y) */
1083         wsprintf(buf, "%d", td->tile_hgt);
1084         WritePrivateProfileString(sec_name, "TileHgt", buf, ini_file);
1085
1086         /* Window size (x) */
1087         wsprintf(buf, "%d", td->cols);
1088         WritePrivateProfileString(sec_name, "NumCols", buf, ini_file);
1089
1090         /* Window size (y) */
1091         wsprintf(buf, "%d", td->rows);
1092         WritePrivateProfileString(sec_name, "NumRows", buf, ini_file);
1093
1094         /* Acquire position */
1095         GetWindowRect(td->w, &rc);
1096
1097         /* Window position (x) */
1098         wsprintf(buf, "%d", rc.left);
1099         WritePrivateProfileString(sec_name, "PositionX", buf, ini_file);
1100
1101         /* Window position (y) */
1102         wsprintf(buf, "%d", rc.top);
1103         WritePrivateProfileString(sec_name, "PositionY", buf, ini_file);
1104 }
1105
1106
1107 /*
1108  * Write the "prefs"
1109  *
1110  * We assume that the windows have all been initialized
1111  */
1112 static void save_prefs(void)
1113 {
1114         int i;
1115
1116         char buf[128];
1117
1118         /* Save the "arg_graphics" flag */
1119         sprintf(buf, "%d", arg_graphics);
1120         WritePrivateProfileString("Angband", "Graphics", buf, ini_file);
1121
1122         /* Save the "arg_bigtile" flag */
1123         strcpy(buf, arg_bigtile ? "1" : "0");
1124         WritePrivateProfileString("Angband", "Bigtile", buf, ini_file);
1125
1126         /* Save the "arg_sound" flag */
1127         strcpy(buf, arg_sound ? "1" : "0");
1128         WritePrivateProfileString("Angband", "Sound", buf, ini_file);
1129
1130         /* bg */
1131         strcpy(buf, use_bg ? "1" : "0");
1132         WritePrivateProfileString("Angband", "BackGround", buf, ini_file);
1133         WritePrivateProfileString("Angband", "BackGroundBitmap", 
1134                 bg_bitmap_file[0] != '\0' ? bg_bitmap_file : "bg.bmp", ini_file);
1135
1136         /* Save window prefs */
1137         for (i = 0; i < MAX_TERM_DATA; ++i)
1138         {
1139                 term_data *td = &data[i];
1140
1141                 sprintf(buf, "Term-%d", i);
1142
1143                 save_prefs_aux(td, buf);
1144         }
1145 }
1146
1147
1148 /*
1149  * Load the "prefs" for a single term
1150  */
1151 static void load_prefs_aux(term_data *td, cptr sec_name)
1152 {
1153         char tmp[1024];
1154
1155         int wid, hgt;
1156
1157         /* Visible */
1158         td->visible = (GetPrivateProfileInt(sec_name, "Visible", td->visible, ini_file) != 0);
1159
1160         /* Desired font, with default */
1161 #ifdef JP
1162         GetPrivateProfileString(sec_name, "Font", "£Í£Ó ¥´¥·¥Ã¥¯", tmp, 127, ini_file);
1163 #else
1164         GetPrivateProfileString(sec_name, "Font", "8X13.FON", tmp, 127, ini_file);
1165 #endif
1166
1167
1168         /* Bizarre */
1169         td->bizarre = (GetPrivateProfileInt(sec_name, "Bizarre", td->bizarre, ini_file) != 0);
1170
1171         /* Analyze font, save desired font name */
1172 #ifdef JP
1173         td->font_want = string_make(tmp);
1174         hgt = 15; wid = 0;
1175         td->lf.lfWidth  = GetPrivateProfileInt(sec_name, "FontWid", wid, ini_file);
1176         td->lf.lfHeight = GetPrivateProfileInt(sec_name, "FontHgt", hgt, ini_file);
1177         td->lf.lfWeight = GetPrivateProfileInt(sec_name, "FontWgt", 0, ini_file);
1178 #else
1179         td->font_want = string_make(analyze_font(tmp, &wid, &hgt));
1180 #endif
1181
1182
1183         /* Tile size */
1184 #ifdef JP
1185         td->tile_wid = GetPrivateProfileInt(sec_name, "TileWid", td->lf.lfWidth, ini_file);
1186         td->tile_hgt = GetPrivateProfileInt(sec_name, "TileHgt", td->lf.lfHeight, ini_file);
1187 #else
1188         td->tile_wid = GetPrivateProfileInt(sec_name, "TileWid", wid, ini_file);
1189         td->tile_hgt = GetPrivateProfileInt(sec_name, "TileHgt", hgt, ini_file);
1190 #endif
1191
1192
1193         /* Window size */
1194         td->cols = GetPrivateProfileInt(sec_name, "NumCols", td->cols, ini_file);
1195         td->rows = GetPrivateProfileInt(sec_name, "NumRows", td->rows, ini_file);
1196
1197         /* Window position */
1198         td->pos_x = GetPrivateProfileInt(sec_name, "PositionX", td->pos_x, ini_file);
1199         td->pos_y = GetPrivateProfileInt(sec_name, "PositionY", td->pos_y, ini_file);
1200 }
1201
1202
1203 /*
1204  * Load the "prefs"
1205  */
1206 static void load_prefs(void)
1207 {
1208         int i;
1209
1210         char buf[1024];
1211
1212         /* Extract the "arg_graphics" flag */
1213         arg_graphics = GetPrivateProfileInt("Angband", "Graphics", GRAPHICS_NONE, ini_file);
1214
1215         /* Extract the "arg_bigtile" flag */
1216         arg_bigtile = GetPrivateProfileInt("Angband", "Bigtile", FALSE, ini_file);
1217         use_bigtile = arg_bigtile;
1218
1219         /* Extract the "arg_sound" flag */
1220         arg_sound = (GetPrivateProfileInt("Angband", "Sound", 0, ini_file) != 0);
1221
1222         /* bg */
1223         use_bg = GetPrivateProfileInt("Angband", "BackGround", 0, ini_file);
1224         GetPrivateProfileString("Angband", "BackGroundBitmap", "bg.bmp", bg_bitmap_file, 1023, ini_file);
1225
1226         /* Load window prefs */
1227         for (i = 0; i < MAX_TERM_DATA; ++i)
1228         {
1229                 term_data *td = &data[i];
1230
1231                 sprintf(buf, "Term-%d", i);
1232
1233                 load_prefs_aux(td, buf);
1234         }
1235 }
1236
1237
1238 /*
1239  * Create the new global palette based on the bitmap palette
1240  * (if any), and the standard 16 entry palette derived from
1241  * "win_clr[]" which is used for the basic 16 Angband colors.
1242  *
1243  * This function is never called before all windows are ready.
1244  *
1245  * This function returns FALSE if the new palette could not be
1246  * prepared, which should normally be a fatal error.  XXX XXX
1247  *
1248  * Note that only some machines actually use a "palette".
1249  */
1250 static int new_palette(void)
1251 {
1252         HPALETTE hBmPal;
1253         HPALETTE hNewPal;
1254         HDC hdc;
1255         int i, nEntries;
1256         int pLogPalSize;
1257         int lppeSize;
1258         LPLOGPALETTE pLogPal;
1259         LPPALETTEENTRY lppe;
1260
1261         term_data *td;
1262
1263
1264         /* This makes no sense */
1265         if (!paletted) return (TRUE);
1266
1267
1268         /* No bitmap */
1269         lppeSize = 0;
1270         lppe = NULL;
1271         nEntries = 0;
1272
1273 #ifdef USE_GRAPHICS
1274
1275         /* Check the bitmap palette */
1276         hBmPal = infGraph.hPalette;
1277
1278         /* Use the bitmap */
1279         if (hBmPal)
1280         {
1281                 lppeSize = 256 * sizeof(PALETTEENTRY);
1282                 lppe = (LPPALETTEENTRY)ralloc(lppeSize);
1283                 nEntries = GetPaletteEntries(hBmPal, 0, 255, lppe);
1284                 if ((nEntries == 0) || (nEntries > 220))
1285                 {
1286                         /* Warn the user */
1287 #ifdef JP
1288                         plog("²èÌ̤ò16¥Ó¥Ã¥È¤«24¥Ó¥Ã¥È¥«¥é¡¼¥â¡¼¥É¤Ë¤·¤Æ²¼¤µ¤¤¡£");
1289 #else
1290                         plog("Please switch to high- or true-color mode.");
1291 #endif
1292
1293
1294                         /* Cleanup */
1295                         rnfree(lppe, lppeSize);
1296
1297                         /* Fail */
1298                         return (FALSE);
1299                 }
1300         }
1301
1302 #endif /* USE_GRAPHICS */
1303
1304         /* Size of palette */
1305         pLogPalSize = sizeof(LOGPALETTE) + (nEntries + 16) * sizeof(PALETTEENTRY);
1306
1307         /* Allocate palette */
1308         pLogPal = (LPLOGPALETTE)ralloc(pLogPalSize);
1309
1310         /* Version */
1311         pLogPal->palVersion = 0x300;
1312
1313         /* Make room for bitmap and normal data */
1314         pLogPal->palNumEntries = nEntries + 16;
1315
1316         /* Save the bitmap data */
1317         for (i = 0; i < nEntries; i++)
1318         {
1319                 pLogPal->palPalEntry[i] = lppe[i];
1320         }
1321
1322         /* Save the normal data */
1323         for (i = 0; i < 16; i++)
1324         {
1325                 LPPALETTEENTRY p;
1326
1327                 /* Access the entry */
1328                 p = &(pLogPal->palPalEntry[i+nEntries]);
1329
1330                 /* Save the colors */
1331                 p->peRed = GetRValue(win_clr[i]);
1332                 p->peGreen = GetGValue(win_clr[i]);
1333                 p->peBlue = GetBValue(win_clr[i]);
1334
1335                 /* Save the flags */
1336                 p->peFlags = PC_NOCOLLAPSE;
1337         }
1338
1339         /* Free something */
1340         if (lppe) rnfree(lppe, lppeSize);
1341
1342         /* Create a new palette, or fail */
1343         hNewPal = CreatePalette(pLogPal);
1344 #ifdef JP
1345         if (!hNewPal) quit("¥Ñ¥ì¥Ã¥È¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¡ª");
1346 #else
1347         if (!hNewPal) quit("Cannot create palette!");
1348 #endif
1349
1350
1351         /* Free the palette */
1352         rnfree(pLogPal, pLogPalSize);
1353
1354         /* Main window */
1355         td = &data[0];
1356
1357         /* Realize the palette */
1358         hdc = GetDC(td->w);
1359         SelectPalette(hdc, hNewPal, 0);
1360         i = RealizePalette(hdc);
1361         ReleaseDC(td->w, hdc);
1362 #ifdef JP
1363         if (i == 0) quit("¥Ñ¥ì¥Ã¥È¤ò¥·¥¹¥Æ¥à¥¨¥ó¥È¥ê¤Ë¥Þ¥Ã¥×¤Ç¤­¤Þ¤»¤ó¡ª");
1364 #else
1365         if (i == 0) quit("Cannot realize palette!");
1366 #endif
1367
1368
1369         /* Sub-windows */
1370         for (i = 1; i < MAX_TERM_DATA; i++)
1371         {
1372                 td = &data[i];
1373
1374                 hdc = GetDC(td->w);
1375                 SelectPalette(hdc, hNewPal, 0);
1376                 ReleaseDC(td->w, hdc);
1377         }
1378
1379         /* Delete old palette */
1380         if (hPal) DeleteObject(hPal);
1381
1382         /* Save new palette */
1383         hPal = hNewPal;
1384
1385         /* Success */
1386         return (TRUE);
1387 }
1388
1389
1390 #ifdef USE_GRAPHICS
1391 /*
1392  * Initialize graphics
1393  */
1394 static bool init_graphics(void)
1395 {
1396         /* Initialize once */
1397         /* if (can_use_graphics != arg_graphics) */
1398         {
1399                 char buf[1024];
1400                 int wid, hgt;
1401                 cptr name;
1402
1403                 if (arg_graphics == GRAPHICS_ADAM_BOLT)
1404                 {
1405                         wid = 16;
1406                         hgt = 16;
1407
1408                         name = "16X16.BMP";
1409
1410                         ANGBAND_GRAF = "new";
1411                 }
1412                 else
1413                 {
1414                         wid = 8;
1415                         hgt = 8;
1416
1417                         name = "8X8.BMP";
1418                         ANGBAND_GRAF = "old";
1419                 }
1420
1421                 /* Access the bitmap file */
1422                 path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, name);
1423
1424                 /* Load the bitmap or quit */
1425                 if (!ReadDIB(data[0].w, buf, &infGraph))
1426                 {
1427 #ifdef JP
1428                         plog_fmt("¥Ó¥Ã¥È¥Þ¥Ã¥× '%s' ¤òÆɤ߹þ¤á¤Þ¤»¤ó¡£", name);
1429 #else
1430                         plog_fmt("Cannot read bitmap file '%s'", name);
1431 #endif
1432
1433                         return (FALSE);
1434                 }
1435
1436                 /* Save the new sizes */
1437                 infGraph.CellWidth = wid;
1438                 infGraph.CellHeight = hgt;
1439
1440 #ifdef USE_TRANSPARENCY
1441
1442                 if (arg_graphics == GRAPHICS_ADAM_BOLT)
1443                 {
1444                         /* Access the mask file */
1445                         path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, "mask.bmp");
1446
1447                         /* Load the bitmap or quit */
1448                         if (!ReadDIB(data[0].w, buf, &infMask))
1449                         {
1450                                 plog_fmt("Cannot read bitmap file '%s'", buf);
1451                                 return (FALSE);
1452                         }
1453                 }
1454
1455 #endif /* USE_TRANSPARENCY */
1456
1457                 /* Activate a palette */
1458                 if (!new_palette())
1459                 {
1460                         /* Free bitmap XXX XXX XXX */
1461
1462                         /* Oops */
1463 #ifdef JP
1464                         plog("¥Ñ¥ì¥Ã¥È¤ò¼Â¸½¤Ç¤­¤Þ¤»¤ó¡ª");
1465 #else
1466                         plog("Cannot activate palette!");
1467 #endif
1468
1469                         return (FALSE);
1470                 }
1471
1472                 /* Graphics available */
1473                 can_use_graphics = arg_graphics;
1474         }
1475
1476         /* Result */
1477         return (can_use_graphics);
1478 }
1479 #endif /* USE_GRAPHICS */
1480
1481
1482 #ifdef USE_SOUND
1483 /*
1484  * Initialize sound
1485  */
1486 static bool init_sound(void)
1487 {
1488         /* Initialize once */
1489         if (!can_use_sound)
1490         {
1491                 int i;
1492
1493                 char wav[128];
1494                 char buf[1024];
1495
1496                 /* Prepare the sounds */
1497                 for (i = 1; i < SOUND_MAX; i++)
1498                 {
1499                         /* Extract name of sound file */
1500                         sprintf(wav, "%s.wav", angband_sound_name[i]);
1501
1502                         /* Access the sound */
1503                         path_build(buf, 1024, ANGBAND_DIR_XTRA_SOUND, wav);
1504
1505                         /* Save the sound filename, if it exists */
1506                         if (check_file(buf)) sound_file[i] = string_make(buf);
1507                 }
1508
1509                 /* Sound available */
1510                 can_use_sound = TRUE;
1511         }
1512
1513         /* Result */
1514         return (can_use_sound);
1515 }
1516 #endif /* USE_SOUND */
1517
1518
1519 /*
1520  * Resize a window
1521  */
1522 static void term_window_resize(term_data *td)
1523 {
1524         /* Require window */
1525         if (!td->w) return;
1526
1527         /* Resize the window */
1528         SetWindowPos(td->w, 0, 0, 0,
1529                      td->size_wid, td->size_hgt,
1530                      SWP_NOMOVE | SWP_NOZORDER);
1531
1532         /* Redraw later */
1533         InvalidateRect(td->w, NULL, TRUE);
1534 }
1535
1536
1537 /*
1538  * Force the use of a new "font file" for a term_data
1539  *
1540  * This function may be called before the "window" is ready
1541  *
1542  * This function returns zero only if everything succeeds.
1543  *
1544  * Note that the "font name" must be capitalized!!!
1545  */
1546 static errr term_force_font(term_data *td, cptr path)
1547 {
1548         int wid, hgt;
1549
1550 #ifndef JP
1551         int i;
1552         char *base;
1553         char buf[1024];
1554 #endif
1555
1556         /* Forget the old font (if needed) */
1557         if (td->font_id) DeleteObject(td->font_id);
1558
1559 #ifndef JP
1560         /* Forget old font */
1561         if (td->font_file)
1562         {
1563                 bool used = FALSE;
1564
1565                 /* Scan windows */
1566                 for (i = 0; i < MAX_TERM_DATA; i++)
1567                 {
1568                         /* Don't check when closing the application */
1569                         if (!path) break;
1570
1571                         /* Check "screen" */
1572                         if ((td != &data[i]) &&
1573                             (data[i].font_file) &&
1574                             (streq(data[i].font_file, td->font_file)))
1575                         {
1576                                 used = TRUE;
1577                         }
1578                 }
1579
1580                 /* Remove unused font resources */
1581                 if (!used) RemoveFontResource(td->font_file);
1582
1583                 /* Free the old name */
1584                 string_free(td->font_file);
1585
1586                 /* Forget it */
1587                 td->font_file = NULL;
1588         }
1589
1590
1591         /* No path given */
1592         if (!path) return (1);
1593
1594
1595         /* Local copy */
1596         strcpy(buf, path);
1597
1598         /* Analyze font path */
1599         base = analyze_font(buf, &wid, &hgt);
1600
1601         /* Verify suffix */
1602         if (!suffix(base, ".FON")) return (1);
1603
1604         /* Verify file */
1605         if (!check_file(buf)) return (1);
1606
1607         /* Load the new font */
1608         if (!AddFontResource(buf)) return (1);
1609
1610         /* Save new font name */
1611         td->font_file = string_make(base);
1612
1613         /* Remove the "suffix" */
1614         base[strlen(base)-4] = '\0';
1615 #endif
1616
1617         /* Create the font (using the 'base' of the font file name!) */
1618 #ifdef JP
1619         td->font_id = CreateFontIndirect(&(td->lf));
1620         wid = td->lf.lfWidth;
1621         hgt = td->lf.lfHeight;
1622         if (!td->font_id) return (1);
1623 #else
1624         td->font_id = CreateFont(hgt, wid, 0, 0, FW_DONTCARE, 0, 0, 0,
1625                                  ANSI_CHARSET, OUT_DEFAULT_PRECIS,
1626                                  CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
1627                                  FIXED_PITCH | FF_DONTCARE, base);
1628 #endif
1629
1630
1631         /* Hack -- Unknown size */
1632         if (!wid || !hgt)
1633         {
1634                 HDC hdcDesktop;
1635                 HFONT hfOld;
1636                 TEXTMETRIC tm;
1637
1638                 /* all this trouble to get the cell size */
1639                 hdcDesktop = GetDC(HWND_DESKTOP);
1640                 hfOld = SelectObject(hdcDesktop, td->font_id);
1641                 GetTextMetrics(hdcDesktop, &tm);
1642                 SelectObject(hdcDesktop, hfOld);
1643                 ReleaseDC(HWND_DESKTOP, hdcDesktop);
1644
1645                 /* Font size info */
1646                 wid = tm.tmAveCharWidth;
1647                 hgt = tm.tmHeight;
1648         }
1649
1650         /* Save the size info */
1651         td->font_wid = wid;
1652         td->font_hgt = hgt;
1653
1654         /* Success */
1655         return (0);
1656 }
1657
1658
1659
1660 /*
1661  * Allow the user to change the font for this window.
1662  */
1663 static void term_change_font(term_data *td)
1664 {
1665 #ifdef JP
1666         CHOOSEFONT cf;
1667
1668         memset(&cf, 0, sizeof(cf));
1669         cf.lStructSize = sizeof(cf);
1670     cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_NOVERTFONTS | CF_INITTOLOGFONTSTRUCT;
1671     cf.lpLogFont = &(td->lf);
1672
1673         if (ChooseFont(&cf))
1674         {
1675                 /* Force the font */
1676                 term_force_font(td, NULL);
1677
1678                 /* Assume not bizarre */
1679                 td->bizarre = TRUE;
1680
1681                 /* Reset the tile info */
1682                 td->tile_wid = td->font_wid;
1683                 td->tile_hgt = td->font_hgt;
1684
1685                 /* Analyze the font */
1686                 term_getsize(td);
1687
1688                 /* Resize the window */
1689                 term_window_resize(td);
1690         }
1691
1692 #else
1693         OPENFILENAME ofn;
1694
1695         char tmp[1024] = "";
1696
1697         /* Extract a default if possible */
1698         if (td->font_file) strcpy(tmp, td->font_file);
1699
1700         /* Ask for a choice */
1701         memset(&ofn, 0, sizeof(ofn));
1702         ofn.lStructSize = sizeof(ofn);
1703         ofn.hwndOwner = data[0].w;
1704         ofn.lpstrFilter = "Angband Font Files (*.fon)\0*.fon\0";
1705         ofn.nFilterIndex = 1;
1706         ofn.lpstrFile = tmp;
1707         ofn.nMaxFile = 128;
1708         ofn.lpstrInitialDir = ANGBAND_DIR_XTRA_FONT;
1709         ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
1710         ofn.lpstrDefExt = "fon";
1711
1712         /* Force choice if legal */
1713         if (GetOpenFileName(&ofn))
1714         {
1715                 /* Force the font */
1716                 if (term_force_font(td, tmp))
1717                 {
1718                         /* Access the standard font file */
1719                         path_build(tmp, 1024, ANGBAND_DIR_XTRA_FONT, "8X13.FON");
1720
1721                         /* Force the use of that font */
1722                         (void)term_force_font(td, tmp);
1723                 }
1724
1725                 /* Assume not bizarre */
1726                 td->bizarre = FALSE;
1727
1728                 /* Reset the tile info */
1729                 td->tile_wid = td->font_wid;
1730                 td->tile_hgt = td->font_hgt;
1731
1732                 /* Analyze the font */
1733                 term_getsize(td);
1734
1735                 /* Resize the window */
1736                 term_window_resize(td);
1737         }
1738 #endif
1739
1740 }
1741
1742
1743
1744 static void windows_map(void);
1745
1746 /*
1747  * Hack -- redraw a term_data
1748  */
1749 static void term_data_redraw(term_data *td)
1750 {
1751         if (td->map_active)
1752         {
1753                 /* Redraw the map */
1754                 windows_map();
1755         }
1756         else
1757         {
1758                 /* Activate the term */
1759                 Term_activate(&td->t);
1760
1761                 /* Redraw the contents */
1762                 Term_redraw();
1763
1764                 /* Restore the term */
1765                 Term_activate(term_screen);
1766         }
1767 }
1768
1769
1770
1771
1772
1773 /*** Function hooks needed by "Term" ***/
1774
1775
1776 #if 0
1777
1778 /*
1779  * Initialize a new Term
1780  */
1781 static void Term_init_win(term *t)
1782 {
1783         /* XXX Unused */
1784 }
1785
1786
1787 /*
1788  * Nuke an old Term
1789  */
1790 static void Term_nuke_win(term *t)
1791 {
1792         /* XXX Unused */
1793 }
1794
1795 #endif
1796
1797
1798 /*
1799  * Interact with the User
1800  */
1801 static errr Term_user_win(int n)
1802 {
1803         /* Success */
1804         return (0);
1805 }
1806
1807
1808 /*
1809  * React to global changes
1810  */
1811 static errr Term_xtra_win_react(void)
1812 {
1813         int i;
1814
1815
1816         /* Simple color */
1817         if (colors16)
1818         {
1819                 /* Save the default colors */
1820                 for (i = 0; i < 256; i++)
1821                 {
1822                         /* Simply accept the desired colors */
1823                         win_pal[i] = angband_color_table[i][0];
1824                 }
1825         }
1826
1827         /* Complex color */
1828         else
1829         {
1830                 COLORREF code;
1831
1832                 byte rv, gv, bv;
1833
1834                 bool change = FALSE;
1835
1836                 /* Save the default colors */
1837                 for (i = 0; i < 256; i++)
1838                 {
1839                         /* Extract desired values */
1840                         rv = angband_color_table[i][1];
1841                         gv = angband_color_table[i][2];
1842                         bv = angband_color_table[i][3];
1843
1844                         /* Extract a full color code */
1845                         code = PALETTERGB(rv, gv, bv);
1846
1847                         /* Activate changes */
1848                         if (win_clr[i] != code)
1849                         {
1850                                 /* Note the change */
1851                                 change = TRUE;
1852
1853                                 /* Apply the desired color */
1854                                 win_clr[i] = code;
1855                         }
1856                 }
1857
1858                 /* Activate the palette if needed */
1859                 if (change) (void)new_palette();
1860         }
1861
1862
1863 #ifdef USE_SOUND
1864
1865         /* Handle "arg_sound" */
1866         if (use_sound != arg_sound)
1867         {
1868                 /* Initialize (if needed) */
1869                 if (arg_sound && !init_sound())
1870                 {
1871                         /* Warning */
1872 #ifdef JP
1873                         plog("¥µ¥¦¥ó¥É¤ò½é´ü²½¤Ç¤­¤Þ¤»¤ó¡ª");
1874 #else
1875                         plog("Cannot initialize sound!");
1876 #endif
1877
1878
1879                         /* Cannot enable */
1880                         arg_sound = FALSE;
1881                 }
1882
1883                 /* Change setting */
1884                 use_sound = arg_sound;
1885         }
1886
1887 #endif
1888
1889
1890 #ifdef USE_GRAPHICS
1891
1892         /* Handle "arg_graphics" */
1893         if (use_graphics != arg_graphics)
1894         {
1895                 /* Initialize (if needed) */
1896                 if (arg_graphics && !init_graphics())
1897                 {
1898                         /* Warning */
1899 #ifdef JP
1900                         plog("¥°¥é¥Õ¥£¥Ã¥¯¥¹¤ò½é´ü²½¤Ç¤­¤Þ¤»¤ó!");
1901 #else
1902                         plog("Cannot initialize graphics!");
1903 #endif
1904
1905
1906                         /* Cannot enable */
1907                         arg_graphics = GRAPHICS_NONE;
1908                 }
1909
1910                 /* Change setting */
1911                 use_graphics = arg_graphics;
1912
1913                 /* Reset visuals */
1914 #ifdef ANGBAND_2_8_1
1915                 reset_visuals();
1916 #else /* ANGBAND_2_8_1 */
1917                 reset_visuals(TRUE);
1918 #endif /* ANGBAND_2_8_1 */
1919         }
1920
1921 #endif /* USE_GRAPHICS */
1922
1923
1924         /* Clean up windows */
1925         for (i = 0; i < MAX_TERM_DATA; i++)
1926         {
1927                 term *old = Term;
1928
1929                 term_data *td = &data[i];
1930
1931                 /* Update resized windows */
1932                 if ((td->cols != td->t.wid) || (td->rows != td->t.hgt))
1933                 {
1934                         /* Activate */
1935                         Term_activate(&td->t);
1936
1937                         /* Hack -- Resize the term */
1938                         Term_resize(td->cols, td->rows);
1939
1940                         /* Redraw the contents */
1941                         Term_redraw();
1942
1943                         /* Restore */
1944                         Term_activate(old);
1945                 }
1946         }
1947
1948
1949         /* Success */
1950         return (0);
1951 }
1952
1953
1954 /*
1955  * Process at least one event
1956  */
1957 static errr Term_xtra_win_event(int v)
1958 {
1959         MSG msg;
1960
1961         /* Wait for an event */
1962         if (v)
1963         {
1964                 /* Block */
1965                 if (GetMessage(&msg, NULL, 0, 0))
1966                 {
1967                         TranslateMessage(&msg);
1968                         DispatchMessage(&msg);
1969                 }
1970         }
1971
1972         /* Check for an event */
1973         else
1974         {
1975                 /* Check */
1976                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1977                 {
1978                         TranslateMessage(&msg);
1979                         DispatchMessage(&msg);
1980                 }
1981         }
1982
1983         /* Success */
1984         return 0;
1985 }
1986
1987
1988 /*
1989  * Process all pending events
1990  */
1991 static errr Term_xtra_win_flush(void)
1992 {
1993         MSG msg;
1994
1995         /* Process all pending events */
1996         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1997         {
1998                 TranslateMessage(&msg);
1999                 DispatchMessage(&msg);
2000         }
2001
2002         /* Success */
2003         return (0);
2004 }
2005
2006
2007 /*
2008  * Hack -- clear the screen
2009  *
2010  * Make this more efficient XXX XXX XXX
2011  */
2012 static errr Term_xtra_win_clear(void)
2013 {
2014         term_data *td = (term_data*)(Term->data);
2015
2016         HDC hdc;
2017         RECT rc;
2018
2019         /* Rectangle to erase */
2020         rc.left = td->size_ow1;
2021         rc.right = rc.left + td->cols * td->tile_wid;
2022         rc.top = td->size_oh1;
2023         rc.bottom = rc.top + td->rows * td->tile_hgt;
2024
2025         /* Erase it */
2026         hdc = GetDC(td->w);
2027         SetBkColor(hdc, RGB(0, 0, 0));
2028         SelectObject(hdc, td->font_id);
2029         ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
2030
2031         /* bg */
2032         if (use_bg)
2033         {
2034                 rc.left = 0; rc.top = 0;
2035                 DrawBG(hdc, &rc);
2036         }
2037         ReleaseDC(td->w, hdc);
2038
2039         /* Success */
2040         return 0;
2041 }
2042
2043
2044 /*
2045  * Hack -- make a noise
2046  */
2047 static errr Term_xtra_win_noise(void)
2048 {
2049         MessageBeep(MB_ICONASTERISK);
2050         return (0);
2051 }
2052
2053
2054 /*
2055  * Hack -- make a sound
2056  */
2057 static errr Term_xtra_win_sound(int v)
2058 {
2059         /* Sound disabled */
2060         if (!use_sound) return (1);
2061
2062         /* Illegal sound */
2063         if ((v < 0) || (v >= SOUND_MAX)) return (1);
2064
2065 #ifdef USE_SOUND
2066
2067         /* Unknown sound */
2068         if (!sound_file[v]) return (1);
2069
2070 #ifdef WIN32
2071
2072         /* Play the sound, catch errors */
2073         return (PlaySound(sound_file[v], 0, SND_FILENAME | SND_ASYNC));
2074
2075 #else /* WIN32 */
2076
2077         /* Play the sound, catch errors */
2078         return (sndPlaySound(sound_file[v], SND_ASYNC));
2079
2080 #endif /* WIN32 */
2081
2082 #else /* USE_SOUND */
2083
2084         /* Oops */
2085         return (1);
2086
2087 #endif /* USE_SOUND */
2088 }
2089
2090
2091 /*
2092  * Delay for "x" milliseconds
2093  */
2094 static int Term_xtra_win_delay(int v)
2095 {
2096
2097 #ifdef WIN32
2098
2099         /* Sleep */
2100         Sleep(v);
2101
2102 #else /* WIN32 */
2103
2104         DWORD t;
2105         MSG msg;
2106
2107         /* Final count */
2108         t = GetTickCount() + v;
2109
2110         /* Wait for it */
2111         while (GetTickCount() < t)
2112         {
2113                 /* Handle messages */
2114                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
2115                 {
2116                         TranslateMessage(&msg);
2117                         DispatchMessage(&msg);
2118                 }
2119         }
2120
2121 #endif /* WIN32 */
2122
2123         /* Success */
2124         return (0);
2125 }
2126
2127
2128 /*
2129  * Do a "special thing"
2130  */
2131 static errr Term_xtra_win(int n, int v)
2132 {
2133         /* Handle a subset of the legal requests */
2134         switch (n)
2135         {
2136                 /* Make a bell sound */
2137                 case TERM_XTRA_NOISE:
2138                 {
2139                         return (Term_xtra_win_noise());
2140                 }
2141
2142                 /* Make a special sound */
2143                 case TERM_XTRA_SOUND:
2144                 {
2145                         return (Term_xtra_win_sound(v));
2146                 }
2147
2148                 /* Process random events */
2149                 case TERM_XTRA_BORED:
2150                 {
2151                         return (Term_xtra_win_event(0));
2152                 }
2153
2154                 /* Process an event */
2155                 case TERM_XTRA_EVENT:
2156                 {
2157                         return (Term_xtra_win_event(v));
2158                 }
2159
2160                 /* Flush all events */
2161                 case TERM_XTRA_FLUSH:
2162                 {
2163                         return (Term_xtra_win_flush());
2164                 }
2165
2166                 /* Clear the screen */
2167                 case TERM_XTRA_CLEAR:
2168                 {
2169                         return (Term_xtra_win_clear());
2170                 }
2171
2172                 /* React to global changes */
2173                 case TERM_XTRA_REACT:
2174                 {
2175                         return (Term_xtra_win_react());
2176                 }
2177
2178                 /* Delay for some milliseconds */
2179                 case TERM_XTRA_DELAY:
2180                 {
2181                         return (Term_xtra_win_delay(v));
2182                 }
2183         }
2184
2185         /* Oops */
2186         return 1;
2187 }
2188
2189
2190
2191 /*
2192  * Low level graphics (Assumes valid input).
2193  *
2194  * Draw a "cursor" at (x,y), using a "yellow box".
2195  */
2196 static errr Term_curs_win(int x, int y)
2197 {
2198         term_data *td = (term_data*)(Term->data);
2199
2200         RECT rc;
2201         HDC hdc;
2202
2203         int tile_wid, tile_hgt;
2204
2205         if (td->map_active)
2206         {
2207                 tile_wid = td->map_tile_wid;
2208                 tile_hgt = td->map_tile_hgt;
2209         }
2210         else
2211         {
2212                 tile_wid = td->tile_wid;
2213                 tile_hgt = td->tile_hgt;
2214         }
2215
2216         /* Frame the grid */
2217         rc.left = x * tile_wid + td->size_ow1;
2218         rc.right = rc.left + tile_wid;
2219         rc.top = y * tile_hgt + td->size_oh1;
2220         rc.bottom = rc.top + tile_hgt;
2221
2222 #ifdef JP
2223         if (x + 1 < Term->wid && 
2224             ((use_bigtile && Term->old->a[y][x+1] == 255)
2225             || (iskanji(Term->old->c[y][x]) && !(Term->old->a[y][x] & 0x80))))
2226 #else
2227         if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x+1] == 255)
2228 #endif
2229                 rc.right += tile_wid;
2230
2231         /* Cursor is done as a yellow "box" */
2232         hdc = GetDC(td->w);
2233         FrameRect(hdc, &rc, hbrYellow);
2234         ReleaseDC(td->w, hdc);
2235
2236         /* Success */
2237         return 0;
2238 }
2239
2240
2241 /*
2242  * Low level graphics (Assumes valid input).
2243  *
2244  * Erase a "block" of "n" characters starting at (x,y).
2245  */
2246 static errr Term_wipe_win(int x, int y, int n)
2247 {
2248         term_data *td = (term_data*)(Term->data);
2249
2250         HDC hdc;
2251         RECT rc;
2252
2253         /* Rectangle to erase in client coords */
2254         rc.left = x * td->tile_wid + td->size_ow1;
2255         rc.right = rc.left + n * td->tile_wid;
2256         rc.top = y * td->tile_hgt + td->size_oh1;
2257         rc.bottom = rc.top + td->tile_hgt;
2258
2259         hdc = GetDC(td->w);
2260         SetBkColor(hdc, RGB(0, 0, 0));
2261         SelectObject(hdc, td->font_id);
2262         /* bg */
2263         if (use_bg)
2264                 DrawBG(hdc, &rc);
2265         else
2266                 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
2267         ReleaseDC(td->w, hdc);
2268
2269         /* Success */
2270         return 0;
2271 }
2272
2273
2274 /*
2275  * Low level graphics.  Assumes valid input.
2276  *
2277  * Draw several ("n") chars, with an attr, at a given location.
2278  *
2279  * All "graphic" data is handled by "Term_pict_win()", below.
2280  *
2281  * One would think there is a more efficient method for telling a window
2282  * what color it should be using to draw with, but perhaps simply changing
2283  * it every time is not too inefficient.  XXX XXX XXX
2284  */
2285 static errr Term_text_win(int x, int y, int n, byte a, const char *s)
2286 {
2287         term_data *td = (term_data*)(Term->data);
2288         RECT rc;
2289         HDC hdc;
2290
2291
2292 #ifdef JP
2293         static HBITMAP  WALL;
2294         static HBRUSH   myBrush, oldBrush;
2295         static HPEN     oldPen;
2296         static bool init_done = FALSE;
2297
2298         if (!init_done){
2299                 WALL = LoadBitmap(hInstance, AppName);
2300                 myBrush = CreatePatternBrush(WALL);
2301                 init_done = TRUE;
2302         }
2303 #endif
2304
2305         /* Total rectangle */
2306         rc.left = x * td->tile_wid + td->size_ow1;
2307         rc.right = rc.left + n * td->tile_wid;
2308         rc.top = y * td->tile_hgt + td->size_oh1;
2309         rc.bottom = rc.top + td->tile_hgt;
2310
2311         /* Acquire DC */
2312         hdc = GetDC(td->w);
2313
2314         /* Background color */
2315         SetBkColor(hdc, RGB(0, 0, 0));
2316
2317         /* Foreground color */
2318         if (colors16)
2319         {
2320                 SetTextColor(hdc, PALETTEINDEX(win_pal[a]));
2321         }
2322         else if (paletted)
2323         {
2324                 SetTextColor(hdc, win_clr[a&0x0F]);
2325         }
2326         else
2327         {
2328                 SetTextColor(hdc, win_clr[a]);
2329         }
2330
2331         /* Use the font */
2332         SelectObject(hdc, td->font_id);
2333         
2334         /* bg */
2335         if (use_bg) SetBkMode(hdc, TRANSPARENT);
2336
2337         /* Bizarre size */
2338         if (td->bizarre ||
2339             (td->tile_hgt != td->font_hgt) ||
2340             (td->tile_wid != td->font_wid))
2341         {
2342                 int i;
2343
2344                 /* Erase complete rectangle */
2345                 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
2346                 
2347                 /* bg */
2348                 if (use_bg) DrawBG(hdc, &rc);
2349
2350                 /* New rectangle */
2351                 rc.left += ((td->tile_wid - td->font_wid) / 2);
2352                 rc.right = rc.left + td->font_wid;
2353                 rc.top += ((td->tile_hgt - td->font_hgt) / 2);
2354                 rc.bottom = rc.top + td->font_hgt;
2355
2356                 /* Dump each character */
2357                 for (i = 0; i < n; i++)
2358                 {
2359 #ifdef JP
2360                         if (use_bigtile && *(s+i)=="¢ò"[0] && *(s+i+1)=="¢ò"[1])
2361                         {
2362                                 rc.right += td->font_wid;
2363
2364                                 oldBrush = SelectObject(hdc, myBrush);
2365                                 oldPen = SelectObject(hdc, GetStockObject(NULL_PEN) );
2366
2367                                 /* Dump the wall */
2368                                 Rectangle(hdc, rc.left, rc.top, rc.right+1, rc.bottom+1);
2369
2370                                 SelectObject(hdc, oldBrush);
2371                                 SelectObject(hdc, oldPen);
2372                                 rc.right -= td->font_wid;
2373
2374                                 /* Advance */
2375                                 i++;
2376                                 rc.left += 2 * td->tile_wid;
2377                                 rc.right += 2 * td->tile_wid;
2378                         }
2379                         else if ( iskanji(*(s+i)) )  /*  £²¥Ð¥¤¥Èʸ»ú  */
2380                         {
2381                                 rc.right += td->font_wid;
2382                                 /* Dump the text */
2383                                 ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc,
2384                                        s+i, 2, NULL);
2385                                 rc.right -= td->font_wid;
2386
2387                                 /* Advance */
2388                                 i++;
2389                                 rc.left += 2 * td->tile_wid;
2390                                 rc.right += 2 * td->tile_wid;
2391                         } else if (*(s+i)==127){
2392                                 oldBrush = SelectObject(hdc, myBrush);
2393                                 oldPen = SelectObject(hdc, GetStockObject(NULL_PEN) );
2394
2395                                 /* Dump the wall */
2396                                 Rectangle(hdc, rc.left, rc.top, rc.right+1, rc.bottom+1);
2397
2398                                 SelectObject(hdc, oldBrush);
2399                                 SelectObject(hdc, oldPen);
2400
2401                                 /* Advance */
2402                                 rc.left += td->tile_wid;
2403                                 rc.right += td->tile_wid;
2404                         } else {
2405                                 /* Dump the text */
2406                                 ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc,
2407                                        s+i, 1, NULL);
2408
2409                                 /* Advance */
2410                                 rc.left += td->tile_wid;
2411                                 rc.right += td->tile_wid;
2412                         }
2413 #else
2414                         /* Dump the text */
2415                         ExtTextOut(hdc, rc.left, rc.top, 0, &rc,
2416                                    s+i, 1, NULL);
2417
2418                         /* Advance */
2419                         rc.left += td->tile_wid;
2420                         rc.right += td->tile_wid;
2421 #endif
2422
2423                 }
2424         }
2425
2426         /* Normal size */
2427         else
2428         {
2429                 /* Dump the text */
2430                 ExtTextOut(hdc, rc.left, rc.top, ETO_OPAQUE | ETO_CLIPPED, &rc,
2431                            s, n, NULL);
2432         }
2433
2434         /* Release DC */
2435         ReleaseDC(td->w, hdc);
2436
2437         /* Success */
2438         return 0;
2439 }
2440
2441
2442 /*
2443  * Low level graphics.  Assumes valid input.
2444  *
2445  * Draw an array of "special" attr/char pairs at the given location.
2446  *
2447  * We use the "Term_pict_win()" function for "graphic" data, which are
2448  * encoded by setting the "high-bits" of both the "attr" and the "char"
2449  * data.  We use the "attr" to represent the "row" of the main bitmap,
2450  * and the "char" to represent the "col" of the main bitmap.  The use
2451  * of this function is induced by the "higher_pict" flag.
2452  *
2453  * If "graphics" is not available, we simply "wipe" the given grids.
2454  */
2455 # ifdef USE_TRANSPARENCY
2456 static errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
2457 # else /* USE_TRANSPARENCY */
2458 static errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp)
2459 # endif /* USE_TRANSPARENCY */
2460 {
2461         term_data *td = (term_data*)(Term->data);
2462
2463 #ifdef USE_GRAPHICS
2464
2465         int i;
2466         int x1, y1, w1, h1;
2467         int x2, y2, w2, h2, tw2;
2468
2469 # ifdef USE_TRANSPARENCY
2470
2471         int x3, y3;
2472
2473         HDC hdcMask;
2474
2475 # endif /* USE_TRANSPARENCY */
2476
2477         HDC hdc;
2478         HDC hdcSrc;
2479         HBITMAP hbmSrcOld;
2480
2481         /* Paranoia */
2482         if (!use_graphics)
2483         {
2484                 /* Erase the grids */
2485                 return (Term_wipe_win(x, y, n));
2486         }
2487
2488         /* Size of bitmap cell */
2489         w1 = infGraph.CellWidth;
2490         h1 = infGraph.CellHeight;
2491
2492         /* Size of window cell */
2493         if (td->map_active)
2494         {
2495                 w2 = td->map_tile_wid;
2496                 h2 = td->map_tile_hgt;
2497         }
2498         else
2499         {
2500                 w2 = td->tile_wid;
2501                 h2 = td->tile_hgt;
2502                 tw2 = w2;
2503
2504                 /* big tile mode */
2505                 if (use_bigtile) tw2 *= 2;
2506         }
2507
2508         /* Location of window cell */
2509         x2 = x * w2 + td->size_ow1;
2510         y2 = y * h2 + td->size_oh1;
2511
2512         /* Info */
2513         hdc = GetDC(td->w);
2514
2515         /* More info */
2516         hdcSrc = CreateCompatibleDC(hdc);
2517         hbmSrcOld = SelectObject(hdcSrc, infGraph.hBitmap);
2518
2519 # ifdef USE_TRANSPARENCY
2520
2521         if (arg_graphics == GRAPHICS_ADAM_BOLT)
2522         {
2523                 hdcMask = CreateCompatibleDC(hdc);
2524                 SelectObject(hdcMask, infMask.hBitmap);
2525         }
2526
2527 # endif /* USE_TRANSPARENCY */
2528
2529         /* Draw attr/char pairs */
2530         for (i = 0; i < n; i++, x2 += w2)
2531         {
2532                 byte a = ap[i];
2533                 char c = cp[i];
2534
2535                 /* Extract picture */
2536                 int row = (a & 0x7F);
2537                 int col = (c & 0x7F);
2538
2539                 /* Location of bitmap cell */
2540                 x1 = col * w1;
2541                 y1 = row * h1;
2542
2543 # ifdef USE_TRANSPARENCY
2544
2545                 if (arg_graphics == GRAPHICS_ADAM_BOLT)
2546                 {
2547                         x3 = (tcp[i] & 0x7F) * w1;
2548                         y3 = (tap[i] & 0x7F) * h1;
2549
2550                         /* Perfect size */
2551                         if ((w1 == tw2) && (h1 == h2))
2552                         {
2553                                 /* Copy the terrain picture from the bitmap to the window */
2554                                 BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, SRCCOPY);
2555
2556                                 /* Mask out the tile */
2557                                 BitBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, SRCAND);
2558
2559                                 /* Draw the tile */
2560                                 BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCPAINT);
2561                         }
2562
2563                         /* Need to stretch */
2564                         else
2565                         {
2566                                 /* Set the correct mode for stretching the tiles */
2567                                 SetStretchBltMode(hdc, COLORONCOLOR);
2568
2569                                 /* Copy the terrain picture from the bitmap to the window */
2570                                 StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, w1, h1, SRCCOPY);
2571
2572                                 /* Only draw if terrain and overlay are different */
2573                                 if ((x1 != x3) || (y1 != y3))
2574                                 {
2575                                         /* Mask out the tile */
2576                                         StretchBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, w1, h1, SRCAND);
2577
2578                                         /* Draw the tile */
2579                                         StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCPAINT);
2580                                 }
2581                         }
2582                 }
2583                 else
2584
2585 # endif /* USE_TRANSPARENCY */
2586
2587                 {
2588                         /* Perfect size */
2589                         if ((w1 == tw2) && (h1 == h2))
2590                         {
2591                                 /* Copy the picture from the bitmap to the window */
2592                                 BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCCOPY);
2593                         }
2594
2595                         /* Need to stretch */
2596                         else
2597                         {
2598                                 /* Set the correct mode for stretching the tiles */
2599                                 SetStretchBltMode(hdc, COLORONCOLOR);
2600
2601                                 /* Copy the picture from the bitmap to the window */
2602                                 StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCCOPY);
2603                         }
2604                 }
2605         }
2606
2607         /* Release */
2608         SelectObject(hdcSrc, hbmSrcOld);
2609         DeleteDC(hdcSrc);
2610
2611 # ifdef USE_TRANSPARENCY
2612
2613         if (arg_graphics == GRAPHICS_ADAM_BOLT)
2614         {
2615                 /* Release */
2616                 SelectObject(hdcMask, hbmSrcOld);
2617                 DeleteDC(hdcMask);
2618         }
2619
2620 # endif /* USE_TRANSPARENCY */
2621
2622         /* Release */
2623         ReleaseDC(td->w, hdc);
2624
2625 #else /* USE_GRAPHICS */
2626
2627         /* Just erase this grid */
2628         return (Term_wipe_win(x, y, n));
2629
2630 #endif /* USE_GRAPHICS */
2631
2632         /* Success */
2633         return 0;
2634 }
2635
2636
2637 #ifdef USE_TRANSPARENCY
2638 extern void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp);
2639 #else /* USE_TRANSPARENCY */
2640 extern void map_info(int y, int x, byte *ap, char *cp);
2641 #endif /* USE_TRANSPARENCY */
2642
2643
2644 static void windows_map(void)
2645 {
2646         term_data *td = &data[0];
2647         byte a, c;
2648         int x, min_x, max_x;
2649         int y, min_y, max_y;
2650
2651 #ifdef USE_TRANSPARENCY
2652         byte ta, tc;
2653 #endif
2654
2655         /* Only in graphics mode */
2656         if (!use_graphics) return;
2657
2658         /* Clear screen */
2659         Term_xtra_win_clear();
2660
2661         td->map_tile_wid = (td->tile_wid * td->cols) / MAX_WID;
2662         td->map_tile_hgt = (td->tile_hgt * td->rows) / MAX_HGT;
2663         td->map_active = TRUE;
2664
2665         {
2666                 min_x = 0;
2667                 min_y = 0;
2668                 max_x = cur_wid;
2669                 max_y = cur_hgt;
2670         }
2671
2672         /* Draw the map */
2673         for (x = min_x; x < max_x; x++)
2674         {
2675                 for (y = min_y; y < max_y; y++)
2676                 {
2677 #ifdef USE_TRANSPARENCY
2678                         map_info(y, x, &a, (char*)&c, &ta, (char*)&tc);
2679 #else /* USE_TRANSPARENCY */
2680                         map_info(y, x, &a, (char*)&c);
2681 #endif /* USE_TRANSPARENCY */
2682
2683                         /* Ignore non-graphics */
2684                         if ((a & 0x80) && (c & 0x80))
2685                         {
2686 #ifdef USE_TRANSPARENCY
2687                                 Term_pict_win(x - min_x, y - min_y, 1, &a, &c, &ta, &tc);
2688 #else /* USE_TRANSPARENCY */
2689                                 Term_pict_win(x - min_x, y - min_y, 1, &a, &c);
2690 #endif /* USE_TRANSPARENCY */
2691                         }
2692                 }
2693         }
2694
2695         /* Hilite the player */
2696         Term_curs_win(px - min_x, py - min_y);
2697
2698         /* Wait for a keypress, flush key buffer */
2699         Term_inkey(&c, TRUE, TRUE);
2700         Term_flush();
2701
2702         /* Switch off the map display */
2703         td->map_active = FALSE;
2704
2705         /* Restore screen */
2706         Term_xtra_win_clear();
2707         Term_redraw();
2708 }
2709
2710
2711 /*** Other routines ***/
2712
2713
2714 /*
2715  * Create and initialize a "term_data" given a title
2716  */
2717 static void term_data_link(term_data *td)
2718 {
2719         term *t = &td->t;
2720
2721         /* Initialize the term */
2722         term_init(t, td->cols, td->rows, td->keys);
2723
2724         /* Use a "software" cursor */
2725         t->soft_cursor = TRUE;
2726
2727         /* Use "Term_pict" for "graphic" data */
2728         t->higher_pict = TRUE;
2729
2730         /* Erase with "white space" */
2731         t->attr_blank = TERM_WHITE;
2732         t->char_blank = ' ';
2733
2734 #if 0
2735         /* Prepare the init/nuke hooks */
2736         t->init_hook = Term_init_win;
2737         t->nuke_hook = Term_nuke_win;
2738 #endif
2739
2740         /* Prepare the template hooks */
2741         t->user_hook = Term_user_win;
2742         t->xtra_hook = Term_xtra_win;
2743         t->curs_hook = Term_curs_win;
2744         t->wipe_hook = Term_wipe_win;
2745         t->text_hook = Term_text_win;
2746         t->pict_hook = Term_pict_win;
2747
2748         /* Remember where we came from */
2749         t->data = (vptr)(td);
2750 }
2751
2752
2753 /*
2754  * Create the windows
2755  *
2756  * First, instantiate the "default" values, then read the "ini_file"
2757  * to over-ride selected values, then create the windows, and fonts.
2758  *
2759  * Must use SW_SHOW not SW_SHOWNA, since on 256 color display
2760  * must make active to realize the palette.  XXX XXX XXX
2761  */
2762 static void init_windows(void)
2763 {
2764         int i;
2765
2766         term_data *td;
2767
2768 #ifndef JP
2769         char buf[1024];
2770 #endif
2771
2772         /* Main window */
2773         td = &data[0];
2774         WIPE(td, term_data);
2775 #ifdef JP
2776         td->s = "ÊѶòÈÚÅÜ";
2777 #else
2778         td->s = angband_term_name[0];
2779 #endif
2780
2781         td->keys = 1024;
2782         td->rows = 24;
2783         td->cols = 80;
2784         td->visible = TRUE;
2785         td->size_ow1 = 2;
2786         td->size_ow2 = 2;
2787         td->size_oh1 = 2;
2788         td->size_oh2 = 2;
2789         td->pos_x = 7 * 30;
2790         td->pos_y = 7 * 20;
2791
2792 #ifdef JP
2793         td->bizarre = TRUE;
2794 #endif
2795         /* Sub windows */
2796         for (i = 1; i < MAX_TERM_DATA; i++)
2797         {
2798                 td = &data[i];
2799                 WIPE(td, term_data);
2800                 td->s = angband_term_name[i];
2801                 td->keys = 16;
2802                 td->rows = 24;
2803                 td->cols = 80;
2804                 td->visible = FALSE;
2805                 td->size_ow1 = 1;
2806                 td->size_ow2 = 1;
2807                 td->size_oh1 = 1;
2808                 td->size_oh2 = 1;
2809                 td->pos_x = (7 - i) * 30;
2810                 td->pos_y = (7 - i) * 20;
2811 #ifdef JP
2812                         td->bizarre = TRUE;
2813 #endif
2814         }
2815
2816
2817         /* Load prefs */
2818         load_prefs();
2819
2820
2821         /* Main window (need these before term_getsize gets called) */
2822         td = &data[0];
2823         td->dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU |
2824                        WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION |
2825                        WS_VISIBLE);
2826         td->dwExStyle = 0;
2827         td->visible = TRUE;
2828
2829         /* Sub windows (need these before term_getsize gets called) */
2830         for (i = 1; i < MAX_TERM_DATA; i++)
2831         {
2832                 td = &data[i];
2833                 td->dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU);
2834                 td->dwExStyle = (WS_EX_TOOLWINDOW);
2835         }
2836
2837
2838         /* All windows */
2839         for (i = 0; i < MAX_TERM_DATA; i++)
2840         {
2841                 td = &data[i];
2842
2843 #ifdef JP
2844                 strncpy(td->lf.lfFaceName, td->font_want, LF_FACESIZE);
2845                 td->lf.lfHeight = td->tile_hgt;
2846                 td->lf.lfWidth  = td->tile_wid;
2847                 td->lf.lfCharSet = SHIFTJIS_CHARSET;
2848                 td->lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
2849                 /* Activate the chosen font */
2850                 term_force_font(td, NULL);
2851                 td->tile_wid = td->font_wid;
2852                 td->tile_hgt = td->font_hgt;
2853 #else
2854                 /* Access the standard font file */
2855                 path_build(buf, 1024, ANGBAND_DIR_XTRA_FONT, td->font_want);
2856
2857                 /* Activate the chosen font */
2858                 if (term_force_font(td, buf))
2859                 {
2860                         /* Access the standard font file */
2861                         path_build(buf, 1024, ANGBAND_DIR_XTRA_FONT, "8X13.FON");
2862
2863                         /* Force the use of that font */
2864                         (void)term_force_font(td, buf);
2865
2866                         /* Oops */
2867                         td->tile_wid = 8;
2868                         td->tile_hgt = 13;
2869
2870                         /* Assume not bizarre */
2871                         td->bizarre = FALSE;
2872                 }
2873 #endif
2874
2875
2876                 /* Analyze the font */
2877                 term_getsize(td);
2878
2879                 /* Resize the window */
2880                 term_window_resize(td);
2881         }
2882
2883
2884         /* Sub windows (reverse order) */
2885         for (i = MAX_TERM_DATA - 1; i >= 1; --i)
2886         {
2887                 td = &data[i];
2888
2889                 my_td = td;
2890                 td->w = CreateWindowEx(td->dwExStyle, AngList,
2891                                        td->s, td->dwStyle,
2892                                        td->pos_x, td->pos_y,
2893                                        td->size_wid, td->size_hgt,
2894                                        HWND_DESKTOP, NULL, hInstance, NULL);
2895                 my_td = NULL;
2896 #ifdef JP
2897                 if (!td->w) quit("¥µ¥Ö¥¦¥£¥ó¥É¥¦¤ËºîÀ®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿");
2898 #else
2899                 if (!td->w) quit("Failed to create sub-window");
2900 #endif
2901
2902
2903                 if (td->visible)
2904                 {
2905                         td->size_hack = TRUE;
2906                         ShowWindow(td->w, SW_SHOW);
2907                         td->size_hack = FALSE;
2908                 }
2909
2910                 term_data_link(td);
2911                 angband_term[i] = &td->t;
2912
2913                 if (td->visible)
2914                 {
2915                         /* Activate the window */
2916                         SetActiveWindow(td->w);
2917
2918                         /* Bring window to top */
2919                         SetWindowPos(td->w, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2920                 }
2921         }
2922
2923
2924         /* Main window */
2925         td = &data[0];
2926
2927         /* Main window */
2928         my_td = td;
2929         td->w = CreateWindowEx(td->dwExStyle, AppName,
2930                                td->s, td->dwStyle,
2931                                td->pos_x, td->pos_y,
2932                                td->size_wid, td->size_hgt,
2933                                HWND_DESKTOP, NULL, hInstance, NULL);
2934         my_td = NULL;
2935 #ifdef JP
2936         if (!td->w) quit("¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤ÎºîÀ®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿");
2937 #else
2938         if (!td->w) quit("Failed to create Angband window");
2939 #endif
2940
2941
2942         term_data_link(td);
2943         angband_term[0] = &td->t;
2944
2945         /* Activate the main window */
2946         SetActiveWindow(td->w);
2947
2948         /* Bring main window back to top */
2949         SetWindowPos(td->w, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2950
2951
2952         /* New palette XXX XXX XXX */
2953         (void)new_palette();
2954
2955
2956         /* Create a "brush" for drawing the "cursor" */
2957         hbrYellow = CreateSolidBrush(win_clr[TERM_YELLOW]);
2958
2959
2960         /* Process pending messages */
2961         (void)Term_xtra_win_flush();
2962 }
2963
2964
2965
2966 /*
2967  * Prepare the menus
2968  */
2969 static void setup_menus(void)
2970 {
2971         int i;
2972
2973         HMENU hm = GetMenu(data[0].w);
2974
2975
2976         /* Menu "File", Disable all */
2977         EnableMenuItem(hm, IDM_FILE_NEW,
2978                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2979         EnableMenuItem(hm, IDM_FILE_OPEN,
2980                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2981         EnableMenuItem(hm, IDM_FILE_SAVE,
2982                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2983         EnableMenuItem(hm, IDM_FILE_EXIT,
2984                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2985         EnableMenuItem(hm, IDM_FILE_SCORE,
2986                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2987
2988
2989         /* No character available */
2990         if (!character_generated)
2991         {
2992                 /* Menu "File", Item "New" */
2993                 EnableMenuItem(hm, IDM_FILE_NEW, MF_BYCOMMAND | MF_ENABLED);
2994
2995                 /* Menu "File", Item "Open" */
2996                 EnableMenuItem(hm, IDM_FILE_OPEN, MF_BYCOMMAND | MF_ENABLED);
2997         }
2998
2999         /* A character available */
3000         if (character_generated)
3001         {
3002                 /* Menu "File", Item "Save" */
3003                 EnableMenuItem(hm, IDM_FILE_SAVE,
3004                            MF_BYCOMMAND | MF_ENABLED);
3005         }
3006
3007         /* Menu "File", Item "Exit" */
3008         EnableMenuItem(hm, IDM_FILE_EXIT,
3009                        MF_BYCOMMAND | MF_ENABLED);
3010
3011         EnableMenuItem(hm, IDM_FILE_SCORE,
3012                        MF_BYCOMMAND | MF_ENABLED);
3013
3014
3015         /* Menu "Window::Visibility" */
3016         for (i = 0; i < MAX_TERM_DATA; i++)
3017         {
3018                 EnableMenuItem(hm, IDM_WINDOW_VIS_0 + i,
3019                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3020
3021                 CheckMenuItem(hm, IDM_WINDOW_VIS_0 + i,
3022                               (data[i].visible ? MF_CHECKED : MF_UNCHECKED));
3023
3024                 EnableMenuItem(hm, IDM_WINDOW_VIS_0 + i,
3025                                MF_BYCOMMAND | MF_ENABLED);
3026         }
3027
3028         /* Menu "Window::Font" */
3029         for (i = 0; i < MAX_TERM_DATA; i++)
3030         {
3031                 EnableMenuItem(hm, IDM_WINDOW_FONT_0 + i,
3032                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3033
3034                 if (data[i].visible)
3035                 {
3036                         EnableMenuItem(hm, IDM_WINDOW_FONT_0 + i,
3037                                        MF_BYCOMMAND | MF_ENABLED);
3038                 }
3039         }
3040
3041         /* Menu "Window::Bizarre Display" */
3042         for (i = 0; i < MAX_TERM_DATA; i++)
3043         {
3044                 EnableMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
3045                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3046
3047                 CheckMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
3048                               (data[i].bizarre ? MF_CHECKED : MF_UNCHECKED));
3049
3050                 if (data[i].visible)
3051                 {
3052                         EnableMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
3053                                    MF_BYCOMMAND | MF_ENABLED);
3054
3055                 }
3056         }
3057
3058         /* Menu "Window::Increase Tile Width" */
3059         for (i = 0; i < MAX_TERM_DATA; i++)
3060         {
3061                 EnableMenuItem(hm, IDM_WINDOW_I_WID_0 + i,
3062                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3063
3064                 if (data[i].visible)
3065                 {
3066                         EnableMenuItem(hm, IDM_WINDOW_I_WID_0 + i,
3067                                    MF_BYCOMMAND | MF_ENABLED);
3068
3069                 }
3070         }
3071
3072         /* Menu "Window::Decrease Tile Width" */
3073         for (i = 0; i < MAX_TERM_DATA; i++)
3074         {
3075                 EnableMenuItem(hm, IDM_WINDOW_D_WID_0 + i,
3076                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3077
3078                 if (data[i].visible)
3079                 {
3080                         EnableMenuItem(hm, IDM_WINDOW_D_WID_0 + i,
3081                                    MF_BYCOMMAND | MF_ENABLED);
3082
3083                 }
3084         }
3085
3086         /* Menu "Window::Increase Tile Height" */
3087         for (i = 0; i < MAX_TERM_DATA; i++)
3088         {
3089                 EnableMenuItem(hm, IDM_WINDOW_I_HGT_0 + i,
3090                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3091
3092                 if (data[i].visible)
3093                 {
3094                         EnableMenuItem(hm, IDM_WINDOW_I_HGT_0 + i,
3095                                    MF_BYCOMMAND | MF_ENABLED);
3096
3097                 }
3098         }
3099
3100         /* Menu "Window::Decrease Tile Height" */
3101         for (i = 0; i < MAX_TERM_DATA; i++)
3102         {
3103                 EnableMenuItem(hm, IDM_WINDOW_D_HGT_0 + i,
3104                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3105
3106                 if (data[i].visible)
3107                 {
3108                         EnableMenuItem(hm, IDM_WINDOW_D_HGT_0 + i,
3109                                    MF_BYCOMMAND | MF_ENABLED);
3110
3111                 }
3112         }
3113
3114         /* Menu "Options", disable all */
3115         EnableMenuItem(hm, IDM_OPTIONS_NO_GRAPHICS,
3116                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3117         EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
3118                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3119         EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
3120                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3121         EnableMenuItem(hm, IDM_OPTIONS_BIGTILE,
3122                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3123         EnableMenuItem(hm, IDM_OPTIONS_SOUND,
3124                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3125 #ifndef JP
3126         EnableMenuItem(hm, IDM_OPTIONS_SAVER,
3127                        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3128 #endif
3129
3130         /* Menu "Options", Item "Map" */
3131         if (use_graphics != GRAPHICS_NONE)
3132                 EnableMenuItem(GetMenu(data[0].w), IDM_OPTIONS_MAP, MF_BYCOMMAND | MF_ENABLED);
3133         else
3134                 EnableMenuItem(GetMenu(data[0].w), IDM_OPTIONS_MAP,
3135                                MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
3136
3137         /* Menu "Options", update all */
3138         CheckMenuItem(hm, IDM_OPTIONS_NO_GRAPHICS,
3139                       (arg_graphics == GRAPHICS_NONE ? MF_CHECKED : MF_UNCHECKED));
3140         CheckMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
3141                       (arg_graphics == GRAPHICS_ORIGINAL ? MF_CHECKED : MF_UNCHECKED));
3142         CheckMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
3143                       (arg_graphics == GRAPHICS_ADAM_BOLT ? MF_CHECKED : MF_UNCHECKED));
3144         CheckMenuItem(hm, IDM_OPTIONS_BIGTILE,
3145                       (arg_bigtile ? MF_CHECKED : MF_UNCHECKED));
3146         CheckMenuItem(hm, IDM_OPTIONS_SOUND,
3147                       (arg_sound ? MF_CHECKED : MF_UNCHECKED));
3148         CheckMenuItem(hm, IDM_OPTIONS_BG,
3149                       (use_bg ? MF_CHECKED : MF_UNCHECKED));
3150 #ifndef JP
3151         CheckMenuItem(hm, IDM_OPTIONS_SAVER,
3152                       (hwndSaver ? MF_CHECKED : MF_UNCHECKED));
3153 #endif
3154
3155 #ifdef USE_GRAPHICS
3156         /* Menu "Options", Item "Graphics" */
3157         EnableMenuItem(hm, IDM_OPTIONS_NO_GRAPHICS, MF_ENABLED);
3158         /* Menu "Options", Item "Graphics" */
3159         EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS, MF_ENABLED);
3160         /* Menu "Options", Item "Graphics" */
3161         EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS, MF_ENABLED);
3162         /* Menu "Options", Item "Graphics" */
3163         EnableMenuItem(hm, IDM_OPTIONS_BIGTILE, MF_ENABLED);
3164 #endif /* USE_GRAPHICS */
3165
3166 #ifdef USE_SOUND
3167         /* Menu "Options", Item "Sound" */
3168         EnableMenuItem(hm, IDM_OPTIONS_SOUND, MF_ENABLED);
3169 #endif /* USE_SOUND */
3170
3171 #ifdef USE_SAVER
3172         /* Menu "Options", Item "ScreenSaver" */
3173         EnableMenuItem(hm, IDM_OPTIONS_SAVER,
3174                        MF_BYCOMMAND | MF_ENABLED);
3175 #endif /* USE_SAVER */
3176 }
3177
3178
3179 /*
3180  * Check for double clicked (or dragged) savefile
3181  *
3182  * Apparently, Windows copies the entire filename into the first
3183  * piece of the "command line string".  Perhaps we should extract
3184  * the "basename" of that filename and append it to the "save" dir.
3185  */
3186 static void check_for_save_file(LPSTR cmd_line)
3187 {
3188         char *s;
3189
3190         /* First arg */
3191         s = cmd_line;
3192
3193         /* No args */
3194         if (!*s) return;
3195
3196         /* Extract filename */
3197         strcat(savefile, s);
3198
3199         /* Validate the file */
3200         validate_file(savefile);
3201
3202         /* Game in progress */
3203         game_in_progress = TRUE;
3204
3205         /* Play game */
3206         play_game(FALSE);
3207 }
3208
3209
3210 /*
3211  * Process a menu command
3212  */
3213 static void process_menus(WORD wCmd)
3214 {
3215         int i;
3216
3217         term_data *td;
3218
3219         OPENFILENAME ofn;
3220
3221         /* Analyze */
3222         switch (wCmd)
3223         {
3224                 /* New game */
3225                 case IDM_FILE_NEW:
3226                 {
3227                         if (!initialized)
3228                         {
3229 #ifdef JP
3230                                 plog("¤Þ¤À½é´ü²½Ãæ¤Ç¤¹...");
3231 #else
3232                                 plog("You cannot do that yet...");
3233 #endif
3234
3235                         }
3236                         else if (game_in_progress)
3237                         {
3238 #ifdef JP
3239                                 plog("¥×¥ì¥¤Ãæ¤Ï¿·¤·¤¤¥²¡¼¥à¤ò»Ï¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡ª");
3240 #else
3241                                 plog("You can't start a new game while you're still playing!");
3242 #endif
3243
3244                         }
3245                         else
3246                         {
3247                                 game_in_progress = TRUE;
3248                                 Term_flush();
3249                                 play_game(TRUE);
3250                                 quit(NULL);
3251                         }
3252                         break;
3253                 }
3254
3255                 /* Open game */
3256                 case IDM_FILE_OPEN:
3257                 {
3258                         if (!initialized)
3259                         {
3260 #ifdef JP
3261                                 plog("¤Þ¤À½é´ü²½Ãæ¤Ç¤¹...");
3262 #else
3263                                 plog("You cannot do that yet...");
3264 #endif
3265
3266                         }
3267                         else if (game_in_progress)
3268                         {
3269 #ifdef JP
3270                                 plog("¥×¥ì¥¤Ãæ¤Ï¥²¡¼¥à¤ò¥í¡¼¥É¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡ª");
3271 #else
3272                                 plog("You can't open a new game while you're still playing!");
3273 #endif
3274
3275                         }
3276                         else
3277                         {
3278                                 memset(&ofn, 0, sizeof(ofn));
3279                                 ofn.lStructSize = sizeof(ofn);
3280                                 ofn.hwndOwner = data[0].w;
3281                                 ofn.lpstrFilter = "Save Files (*.)\0*\0";
3282                                 ofn.nFilterIndex = 1;
3283                                 ofn.lpstrFile = savefile;
3284                                 ofn.nMaxFile = 1024;
3285                                 ofn.lpstrInitialDir = ANGBAND_DIR_SAVE;
3286                                 ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
3287
3288                                 if (GetOpenFileName(&ofn))
3289                                 {
3290                                         /* Load 'savefile' */
3291                                         validate_file(savefile);
3292                                         game_in_progress = TRUE;
3293                                         Term_flush();
3294                                         play_game(FALSE);
3295                                         quit(NULL);
3296                                 }
3297                         }
3298                         break;
3299                 }
3300
3301                 /* Save game */
3302                 case IDM_FILE_SAVE:
3303                 {
3304                         if (game_in_progress && character_generated)
3305                         {
3306                                 /* Paranoia */
3307                                 if (!can_save)
3308                                 {
3309 #ifdef JP
3310                                         plog("º£¤Ï¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3311 #else
3312                                         plog("You may not do that right now.");
3313 #endif
3314
3315                                         break;
3316                                 }
3317
3318                                 /* Hack -- Forget messages */
3319                                 msg_flag = FALSE;
3320
3321                                 /* Save the game */
3322 #ifdef ZANGBAND
3323                                 do_cmd_save_game(FALSE);
3324 #else /* ZANGBAND */
3325                                 do_cmd_save_game();
3326 #endif /* ZANGBAND */
3327                         }
3328                         else
3329                         {
3330 #ifdef JP
3331                                 plog("º£¡¢¥»¡¼¥Ö¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£");
3332 #else
3333                                 plog("You may not do that right now.");
3334 #endif
3335
3336                         }
3337                         break;
3338                 }
3339
3340                 /* Exit */
3341                 case IDM_FILE_EXIT:
3342                 {
3343                         if (game_in_progress && character_generated)
3344                         {
3345                                 /* Paranoia */
3346                                 if (!can_save)
3347                                 {
3348 #ifdef JP
3349                                 plog("º£¤Ï½ªÎ»¤Ç¤­¤Þ¤»¤ó¡£");
3350 #else
3351                                         plog("You may not do that right now.");
3352 #endif
3353
3354                                         break;
3355                                 }
3356
3357                                 /* Hack -- Forget messages */
3358                                 msg_flag = FALSE;
3359
3360                                 forget_lite();
3361                                 forget_view();
3362                                 clear_mon_lite();
3363
3364                                 /* Save the game */
3365 #ifdef ZANGBAND
3366                                 do_cmd_save_game(FALSE);
3367 #else /* ZANGBAND */
3368                                 do_cmd_save_game();
3369 #endif /* ZANGBAND */
3370                         }
3371                         quit(NULL);
3372                         break;
3373                 }
3374
3375                 /* Show scores */
3376                 case IDM_FILE_SCORE:
3377                 {
3378                         char buf[1024];
3379
3380                         /* Build the filename */
3381                         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
3382
3383                         /* Open the binary high score file, for reading */
3384                         highscore_fd = fd_open(buf, O_RDONLY);
3385
3386                         /* Paranoia -- No score file */
3387                         if (highscore_fd < 0)
3388                         {
3389                                 msg_print("Score file unavailable.");
3390                         }
3391                         else
3392                         {
3393                                 /* Save Screen */
3394                                 screen_save();
3395
3396                                 /* Clear screen */
3397                                 Term_clear();
3398
3399                                 /* Display the scores */
3400                                 display_scores_aux(0, MAX_HISCORES, -1, NULL);
3401
3402                                 /* Shut the high score file */
3403                                 (void)fd_close(highscore_fd);
3404
3405                                 /* Forget the high score fd */
3406                                 highscore_fd = -1;
3407
3408                                 /* Load screen */
3409                                 screen_load();
3410
3411                                 /* Hack - Flush it */
3412                                 Term_fresh();
3413                         }
3414
3415                         break;
3416                 }
3417
3418
3419                 case IDM_WINDOW_VIS_0:
3420                 {
3421 #ifdef JP
3422                         plog("¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤ÏÈóɽ¼¨¤Ë¤Ç¤­¤Þ¤»¤ó¡ª");
3423 #else
3424                         plog("You are not allowed to do that!");
3425 #endif
3426
3427
3428                         break;
3429                 }
3430
3431                 /* Window visibility */
3432                 case IDM_WINDOW_VIS_1:
3433                 case IDM_WINDOW_VIS_2:
3434                 case IDM_WINDOW_VIS_3:
3435                 case IDM_WINDOW_VIS_4:
3436                 case IDM_WINDOW_VIS_5:
3437                 case IDM_WINDOW_VIS_6:
3438                 case IDM_WINDOW_VIS_7:
3439                 {
3440                         i = wCmd - IDM_WINDOW_VIS_0;
3441
3442                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3443
3444                         td = &data[i];
3445
3446                         if (!td->visible)
3447                         {
3448                                 td->visible = TRUE;
3449                                 ShowWindow(td->w, SW_SHOW);
3450                                 term_data_redraw(td);
3451                         }
3452                         else
3453                         {
3454                                 td->visible = FALSE;
3455                                 ShowWindow(td->w, SW_HIDE);
3456                         }
3457
3458                         break;
3459                 }
3460
3461                 /* Window fonts */
3462                 case IDM_WINDOW_FONT_0:
3463                 case IDM_WINDOW_FONT_1:
3464                 case IDM_WINDOW_FONT_2:
3465                 case IDM_WINDOW_FONT_3:
3466                 case IDM_WINDOW_FONT_4:
3467                 case IDM_WINDOW_FONT_5:
3468                 case IDM_WINDOW_FONT_6:
3469                 case IDM_WINDOW_FONT_7:
3470                 {
3471                         i = wCmd - IDM_WINDOW_FONT_0;
3472
3473                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3474
3475                         td = &data[i];
3476
3477                         term_change_font(td);
3478
3479                         break;
3480                 }
3481
3482                 /* Bizarre Display */
3483                 case IDM_WINDOW_BIZ_0:
3484                 case IDM_WINDOW_BIZ_1:
3485                 case IDM_WINDOW_BIZ_2:
3486                 case IDM_WINDOW_BIZ_3:
3487                 case IDM_WINDOW_BIZ_4:
3488                 case IDM_WINDOW_BIZ_5:
3489                 case IDM_WINDOW_BIZ_6:
3490                 case IDM_WINDOW_BIZ_7:
3491                 {
3492                         i = wCmd - IDM_WINDOW_BIZ_0;
3493
3494                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3495
3496                         td = &data[i];
3497
3498                         td->bizarre = !td->bizarre;
3499
3500                         term_getsize(td);
3501
3502                         term_window_resize(td);
3503
3504                         break;
3505                 }
3506
3507                 /* Increase Tile Width */
3508                 case IDM_WINDOW_I_WID_0:
3509                 case IDM_WINDOW_I_WID_1:
3510                 case IDM_WINDOW_I_WID_2:
3511                 case IDM_WINDOW_I_WID_3:
3512                 case IDM_WINDOW_I_WID_4:
3513                 case IDM_WINDOW_I_WID_5:
3514                 case IDM_WINDOW_I_WID_6:
3515                 case IDM_WINDOW_I_WID_7:
3516                 {
3517                         i = wCmd - IDM_WINDOW_I_WID_0;
3518
3519                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3520
3521                         td = &data[i];
3522
3523                         td->tile_wid += 1;
3524
3525                         term_getsize(td);
3526
3527                         term_window_resize(td);
3528
3529                         break;
3530                 }
3531
3532                 /* Decrease Tile Height */
3533                 case IDM_WINDOW_D_WID_0:
3534                 case IDM_WINDOW_D_WID_1:
3535                 case IDM_WINDOW_D_WID_2:
3536                 case IDM_WINDOW_D_WID_3:
3537                 case IDM_WINDOW_D_WID_4:
3538                 case IDM_WINDOW_D_WID_5:
3539                 case IDM_WINDOW_D_WID_6:
3540                 case IDM_WINDOW_D_WID_7:
3541                 {
3542                         i = wCmd - IDM_WINDOW_D_WID_0;
3543
3544                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3545
3546                         td = &data[i];
3547
3548                         td->tile_wid -= 1;
3549
3550                         term_getsize(td);
3551
3552                         term_window_resize(td);
3553
3554                         break;
3555                 }
3556
3557                 /* Increase Tile Height */
3558                 case IDM_WINDOW_I_HGT_0:
3559                 case IDM_WINDOW_I_HGT_1:
3560                 case IDM_WINDOW_I_HGT_2:
3561                 case IDM_WINDOW_I_HGT_3:
3562                 case IDM_WINDOW_I_HGT_4:
3563                 case IDM_WINDOW_I_HGT_5:
3564                 case IDM_WINDOW_I_HGT_6:
3565                 case IDM_WINDOW_I_HGT_7:
3566                 {
3567                         i = wCmd - IDM_WINDOW_I_HGT_0;
3568
3569                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3570
3571                         td = &data[i];
3572
3573                         td->tile_hgt += 1;
3574
3575                         term_getsize(td);
3576
3577                         term_window_resize(td);
3578
3579                         break;
3580                 }
3581
3582                 /* Decrease Tile Height */
3583                 case IDM_WINDOW_D_HGT_0:
3584                 case IDM_WINDOW_D_HGT_1:
3585                 case IDM_WINDOW_D_HGT_2:
3586                 case IDM_WINDOW_D_HGT_3:
3587                 case IDM_WINDOW_D_HGT_4:
3588                 case IDM_WINDOW_D_HGT_5:
3589                 case IDM_WINDOW_D_HGT_6:
3590                 case IDM_WINDOW_D_HGT_7:
3591                 {
3592                         i = wCmd - IDM_WINDOW_D_HGT_0;
3593
3594                         if ((i < 0) || (i >= MAX_TERM_DATA)) break;
3595
3596                         td = &data[i];
3597
3598                         td->tile_hgt -= 1;
3599
3600                         term_getsize(td);
3601
3602                         term_window_resize(td);
3603
3604                         break;
3605                 }
3606
3607                 case IDM_OPTIONS_NO_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_NONE)
3618                         {
3619                                 arg_graphics = GRAPHICS_NONE;
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_OLD_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_ORIGINAL)
3642                         {
3643                                 arg_graphics = GRAPHICS_ORIGINAL;
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_NEW_GRAPHICS:
3656                 {
3657                         /* Paranoia */
3658                         if (!inkey_flag)
3659                         {
3660                                 plog("You may not do that right now.");
3661                                 break;
3662                         }
3663
3664                         /* Toggle "arg_graphics" */
3665                         if (arg_graphics != GRAPHICS_ADAM_BOLT)
3666                         {
3667                                 arg_graphics = GRAPHICS_ADAM_BOLT;
3668
3669                                 /* React to changes */
3670                                 Term_xtra_win_react();
3671
3672                                 /* Hack -- Force redraw */
3673                                 Term_key_push(KTRL('R'));
3674                         }
3675
3676                         break;
3677                 }
3678
3679                 case IDM_OPTIONS_BIGTILE:
3680                 {
3681                         term_data *td = &data[0];
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_bigtile = !arg_bigtile;
3692
3693                         /* Activate */
3694                         Term_activate(&td->t);
3695
3696                         /* Resize the term */
3697                         Term_resize(td->cols, td->rows);
3698
3699                         /* Redraw later */
3700                         InvalidateRect(td->w, NULL, TRUE);
3701
3702                         break;
3703                 }
3704
3705                 case IDM_OPTIONS_SOUND:
3706                 {
3707                         /* Paranoia */
3708                         if (!inkey_flag)
3709                         {
3710                                 plog("You may not do that right now.");
3711                                 break;
3712                         }
3713
3714                         /* Toggle "arg_sound" */
3715                         arg_sound = !arg_sound;
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_BG:
3728                 {
3729                         /* Paranoia */
3730                         if (!inkey_flag)
3731                         {
3732                                 plog("You may not do that right now.");
3733                                 break;
3734                         }
3735
3736                         /* Toggle "use_bg" */
3737                         use_bg = !use_bg;
3738
3739                         init_bg();
3740
3741                         /* React to changes */
3742                         Term_xtra_win_react();
3743
3744                         /* Hack -- Force redraw */
3745                         Term_key_push(KTRL('R'));
3746
3747                         break;
3748                 }
3749
3750                 /* bg */
3751                 case IDM_OPTIONS_OPEN_BG:
3752                 {
3753                         /* Paranoia */
3754                         if (!inkey_flag)
3755                         {
3756                                 plog("You may not do that right now.");
3757                                 break;
3758                         }
3759                         else
3760                         {
3761                                 memset(&ofn, 0, sizeof(ofn));
3762                                 ofn.lStructSize = sizeof(ofn);
3763                                 ofn.hwndOwner = data[0].w;
3764                                 ofn.lpstrFilter = "Bitmap Files (*.bmp)\0*.bmp\0";
3765                                 ofn.nFilterIndex = 1;
3766                                 ofn.lpstrFile = bg_bitmap_file;
3767                                 ofn.nMaxFile = 1023;
3768                                 ofn.lpstrInitialDir = NULL;
3769 #ifdef JP
3770                                 ofn.lpstrTitle = "ÊÉ»æ¤òÁª¤ó¤Ç¤Í¡£";
3771 #else
3772                                 ofn.lpstrTitle = "Choose wall paper.";
3773 #endif
3774                                 ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
3775
3776                                 if (GetOpenFileName(&ofn))
3777                                 {
3778                                         /* Load 'savefile' */
3779                                         use_bg = 1;
3780                                         init_bg();
3781                                 }
3782
3783                                 /* React to changes */
3784                                 Term_xtra_win_react();
3785
3786                                 /* Hack -- Force redraw */
3787                                 Term_key_push(KTRL('R'));
3788                         }
3789                         break;
3790                 }
3791
3792                 case IDM_DUMP_SCREEN_HTML:
3793                 {
3794                         static char buf[1024] = "";
3795                         memset(&ofn, 0, sizeof(ofn));
3796                         ofn.lStructSize = sizeof(ofn);
3797                         ofn.hwndOwner = data[0].w;
3798                         ofn.lpstrFilter = "HTML Files (*.html)\0*.html\0";
3799                         ofn.nFilterIndex = 1;
3800                         ofn.lpstrFile = buf;
3801                         ofn.nMaxFile = 1023;
3802                         ofn.lpstrDefExt = "html";
3803                         ofn.lpstrInitialDir = NULL;
3804 #ifdef JP
3805                         ofn.lpstrTitle = "HTML¤Ç¥¹¥¯¥ê¡¼¥ó¥À¥ó¥×¤òÊݸ";
3806 #else
3807                         ofn.lpstrTitle = "Save screen dump as HTML.";
3808 #endif
3809                         ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
3810
3811                         if (GetSaveFileName(&ofn))
3812                         {
3813                                 extern void do_cmd_save_screen_html_aux(char *filename, int message);
3814                                 do_cmd_save_screen_html_aux(buf, 0);
3815                         }
3816                         break;
3817                 }
3818
3819 #ifdef USE_SAVER
3820
3821                 case IDM_OPTIONS_SAVER:
3822                 {
3823                         if (hwndSaver)
3824                         {
3825                                 DestroyWindow(hwndSaver);
3826                                 hwndSaver = NULL;
3827                         }
3828                         else
3829                         {
3830                                 /* Create a screen scaver window */
3831                                 hwndSaver = CreateWindowEx(WS_EX_TOPMOST, "WindowsScreenSaverClass",
3832                                                            "Angband Screensaver",
3833                                                            WS_POPUP | WS_MAXIMIZE | WS_VISIBLE,
3834                                                            0, 0, GetSystemMetrics(SM_CXSCREEN),
3835                                                            GetSystemMetrics(SM_CYSCREEN),
3836                                                            NULL, NULL, hInstance, NULL);
3837
3838                                 if (hwndSaver)
3839                                 {
3840                                         /* Push the window to the bottom XXX XXX XXX */
3841                                         SetWindowPos(hwndSaver, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
3842                                 }
3843                                 else
3844                                 {
3845 #ifdef JP
3846                                         plog("¥¦¥£¥ó¥É¥¦¤òºîÀ®½ÐÍè¤Þ¤»¤ó");
3847 #else
3848                                         plog("Failed to create saver window");
3849 #endif
3850
3851                                 }
3852                         }
3853                         break;
3854                 }
3855
3856 #endif
3857
3858                 case IDM_OPTIONS_MAP:
3859                 {
3860                         windows_map();
3861                         break;
3862                 }
3863
3864                 case IDM_HELP_CONTENTS:
3865                 {
3866 #ifdef HTML_HELP
3867                         char tmp[1024];
3868                         path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "zangband.chm");
3869                         if (check_file(tmp))
3870                         {
3871                                 HtmlHelp(data[0].w, tmp, HH_DISPLAY_TOPIC, 0);
3872                         }
3873                         else
3874                         {
3875 #ifdef JP
3876                                 plog_fmt("¥Ø¥ë¥×¥Õ¥¡¥¤¥ë[%s]¤¬¸«ÉÕ¤«¤ê¤Þ¤»¤ó¡£", tmp);
3877                                 plog("Âå¤ï¤ê¤Ë¥ª¥ó¥é¥¤¥ó¥Ø¥ë¥×¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£");
3878 #else
3879                                 plog_fmt("Cannot find help file: %s", tmp);
3880                                 plog("Use the online help files instead.");
3881 #endif
3882
3883                         }
3884                         break;
3885 #else /* HTML_HELP */
3886                         char buf[1024];
3887                         char tmp[1024];
3888                         path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "zangband.hlp");
3889                         if (check_file(tmp))
3890                         {
3891                                 sprintf(buf, "winhelp.exe %s", tmp);
3892                                 WinExec(buf, SW_NORMAL);
3893                         }
3894                         else
3895                         {
3896 #ifdef JP
3897                                 plog_fmt("¥Ø¥ë¥×¥Õ¥¡¥¤¥ë[%s]¤¬¸«ÉÕ¤«¤ê¤Þ¤»¤ó¡£", tmp);
3898                                 plog("Âå¤ï¤ê¤Ë¥ª¥ó¥é¥¤¥ó¥Ø¥ë¥×¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£");
3899 #else
3900                                 plog_fmt("Cannot find help file: %s", tmp);
3901                                 plog("Use the online help files instead.");
3902 #endif
3903
3904                         }
3905                         break;
3906 #endif /* HTML_HELP */
3907                 }
3908         }
3909 }
3910
3911
3912
3913 #ifdef __MWERKS__
3914 LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
3915                                   WPARAM wParam, LPARAM lParam);
3916 LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
3917                                   WPARAM wParam, LPARAM lParam)
3918 #else /* __MWERKS__ */
3919 LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
3920                                           WPARAM wParam, LPARAM lParam)
3921 #endif /* __MWERKS__ */
3922 {
3923         PAINTSTRUCT ps;
3924         HDC hdc;
3925         term_data *td;
3926 #if 0
3927         MINMAXINFO FAR *lpmmi;
3928         RECT rc;
3929 #endif
3930         int i;
3931
3932
3933         /* Acquire proper "term_data" info */
3934         td = (term_data *)GetWindowLong(hWnd, 0);
3935
3936         /* Handle message */
3937         switch (uMsg)
3938         {
3939                 /* XXX XXX XXX */
3940                 case WM_NCCREATE:
3941                 {
3942                         SetWindowLong(hWnd, 0, (LONG)(my_td));
3943                         break;
3944                 }
3945
3946                 /* XXX XXX XXX */
3947                 case WM_CREATE:
3948                 {
3949                         return 0;
3950                 }
3951
3952                 case WM_GETMINMAXINFO:
3953                 {
3954                         MINMAXINFO FAR *lpmmi;
3955                         RECT rc;
3956
3957                         lpmmi = (MINMAXINFO FAR *)lParam;
3958
3959                         /* this message was sent before WM_NCCREATE */
3960                         if (!td) return 1;
3961
3962                         /* Minimum window size is 80x24 */
3963                         rc.left = rc.top = 0;
3964                         rc.right = rc.left + 80 * td->tile_wid + td->size_ow1 + td->size_ow2;
3965                         rc.bottom = rc.top + 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
3966
3967                         /* Adjust */
3968                         AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
3969
3970                         /* Save minimum size */
3971                         lpmmi->ptMinTrackSize.x = rc.right - rc.left;
3972                         lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;
3973
3974                         return 0;
3975                 }
3976
3977                 case WM_PAINT:
3978                 {
3979                         BeginPaint(hWnd, &ps);
3980                         if (td) term_data_redraw(td);
3981                         EndPaint(hWnd, &ps);
3982                         ValidateRect(hWnd, NULL);
3983                         return 0;
3984                 }
3985
3986                 case WM_SYSKEYDOWN:
3987                 case WM_KEYDOWN:
3988                 {
3989                         bool mc = FALSE;
3990                         bool ms = FALSE;
3991                         bool ma = FALSE;
3992
3993                         /* Extract the modifiers */
3994                         if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
3995                         if (GetKeyState(VK_SHIFT)   & 0x8000) ms = TRUE;
3996                         if (GetKeyState(VK_MENU)    & 0x8000) ma = TRUE;
3997
3998                         /* Handle "special" keys */
3999                         if (special_key[(byte)(wParam)] || (ma && !ignore_key[(byte)(wParam)]) )
4000                         {
4001                                 /* Begin the macro trigger */
4002                                 Term_keypress(31);
4003
4004                                 /* Send the modifiers */
4005                                 if (mc) Term_keypress('C');
4006                                 if (ms) Term_keypress('S');
4007                                 if (ma) Term_keypress('A');
4008
4009                                 /* Extract "scan code" */
4010                                 i = LOBYTE(HIWORD(lParam));
4011
4012                                 /* Introduce the scan code */
4013                                 Term_keypress('x');
4014
4015                                 /* Encode the hexidecimal scan code */
4016                                 Term_keypress(hexsym[i/16]);
4017                                 Term_keypress(hexsym[i%16]);
4018
4019                                 /* End the macro trigger */
4020                                 Term_keypress(13);
4021
4022                                 return 0;
4023                         }
4024
4025                         break;
4026                 }
4027
4028                 case WM_CHAR:
4029                 {
4030                         Term_keypress(wParam);
4031                         return 0;
4032                 }
4033
4034                 case WM_INITMENU:
4035                 {
4036                         setup_menus();
4037                         return 0;
4038                 }
4039
4040                 case WM_CLOSE:
4041                 {
4042                         if (game_in_progress && character_generated)
4043                         {
4044                                 if (!can_save)
4045                                 {
4046                                         plog("You may not do that right now.");
4047                                         return 0;
4048                                 }
4049
4050                                 /* Hack -- Forget messages */
4051                                 msg_flag = FALSE;
4052
4053                                 forget_lite();
4054                                 forget_view();
4055                                 clear_mon_lite();
4056
4057                                 /* Save the game */
4058 #ifdef ZANGBAND
4059                                 do_cmd_save_game(FALSE);
4060 #else /* ZANGBAND */
4061                                 do_cmd_save_game();
4062 #endif /* ZANGBAND */
4063                         }
4064                         quit(NULL);
4065                         return 0;
4066                 }
4067
4068                 case WM_QUIT:
4069                 {
4070                         quit(NULL);
4071                         return 0;
4072                 }
4073
4074                 case WM_COMMAND:
4075                 {
4076                         process_menus(LOWORD(wParam));
4077                         return 0;
4078                 }
4079
4080                 case WM_SIZE:
4081                 {
4082                         /* this message was sent before WM_NCCREATE */
4083                         if (!td) return 1;
4084
4085                         /* it was sent from inside CreateWindowEx */
4086                         if (!td->w) return 1;
4087
4088                         /* was sent from WM_SIZE */
4089                         if (td->size_hack) return 1;
4090
4091                         switch (wParam)
4092                         {
4093                                 case SIZE_MINIMIZED:
4094                                 {
4095                                         /* Hide sub-windows */
4096                                         for (i = 1; i < MAX_TERM_DATA; i++)
4097                                         {
4098                                                 if (data[i].visible) ShowWindow(data[i].w, SW_HIDE);
4099                                         }
4100                                         return 0;
4101                                 }
4102
4103                                 case SIZE_MAXIMIZED:
4104                                 {
4105                                         /* fall through XXX XXX XXX */
4106                                 }
4107
4108                                 case SIZE_RESTORED:
4109                                 {
4110                                         uint cols = (LOWORD(lParam) - td->size_ow1) / td->tile_wid;
4111                                         uint rows = (HIWORD(lParam) - td->size_oh1) / td->tile_hgt;
4112
4113                                         /* New size */
4114                                         if ((td->cols != cols) || (td->rows != rows))
4115                                         {
4116                                                 /* Save the new size */
4117                                                 td->cols = cols;
4118                                                 td->rows = rows;
4119
4120                                                 /* Activate */
4121                                                 Term_activate(&td->t);
4122
4123                                                 /* Resize the term */
4124                                                 Term_resize(td->cols, td->rows);
4125
4126                                                 /* Redraw later */
4127                                                 InvalidateRect(td->w, NULL, TRUE);
4128                                         }
4129
4130                                         td->size_hack = TRUE;
4131
4132                                         /* Show sub-windows */
4133                                         for (i = 1; i < MAX_TERM_DATA; i++)
4134                                         {
4135                                                 if (data[i].visible) ShowWindow(data[i].w, SW_SHOW);
4136                                         }
4137
4138                                         td->size_hack = FALSE;
4139
4140                                         return 0;
4141                                 }
4142                         }
4143                         break;
4144                 }
4145
4146                 case WM_PALETTECHANGED:
4147                 {
4148                         /* Ignore if palette change caused by itself */
4149                         if ((HWND)wParam == hWnd) return 0;
4150
4151                         /* Fall through... */
4152                 }
4153
4154                 case WM_QUERYNEWPALETTE:
4155                 {
4156                         if (!paletted) return 0;
4157
4158                         hdc = GetDC(hWnd);
4159
4160                         SelectPalette(hdc, hPal, FALSE);
4161
4162                         i = RealizePalette(hdc);
4163
4164                         /* if any palette entries changed, repaint the window. */
4165                         if (i) InvalidateRect(hWnd, NULL, TRUE);
4166
4167                         ReleaseDC(hWnd, hdc);
4168
4169                         return 0;
4170                 }
4171
4172                 case WM_ACTIVATE:
4173                 {
4174                         if (wParam && !HIWORD(lParam))
4175                         {
4176                                 /* Do something to sub-windows */
4177                                 for (i = 1; i < MAX_TERM_DATA; i++)
4178                                 {
4179                                         SetWindowPos(data[i].w, hWnd, 0, 0, 0, 0,
4180                                                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
4181                                 }
4182
4183                                 /* Focus on main window */
4184                                 SetFocus(hWnd);
4185
4186                                 return 0;
4187                         }
4188
4189                         break;
4190                 }
4191         }
4192
4193         return DefWindowProc(hWnd, uMsg, wParam, lParam);
4194 }
4195
4196
4197 #ifdef __MWERKS__
4198 LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
4199                                            WPARAM wParam, LPARAM lParam);
4200 LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
4201                                            WPARAM wParam, LPARAM lParam)
4202 #else /* __MWERKS__ */
4203 LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
4204                                            WPARAM wParam, LPARAM lParam)
4205 #endif /* __MWERKS__ */
4206 {
4207         term_data *td;
4208 #if 0
4209         MINMAXINFO FAR *lpmmi;
4210         RECT rc;
4211 #endif
4212         PAINTSTRUCT ps;
4213         HDC hdc;
4214         int i;
4215
4216
4217         /* Acquire proper "term_data" info */
4218         td = (term_data *)GetWindowLong(hWnd, 0);
4219
4220         /* Process message */
4221         switch (uMsg)
4222         {
4223                 /* XXX XXX XXX */
4224                 case WM_NCCREATE:
4225                 {
4226                         SetWindowLong(hWnd, 0, (LONG)(my_td));
4227                         break;
4228                 }
4229
4230                 /* XXX XXX XXX */
4231                 case WM_CREATE:
4232                 {
4233                         return 0;
4234                 }
4235
4236                 case WM_GETMINMAXINFO:
4237                 {
4238                         MINMAXINFO FAR *lpmmi;
4239                         RECT rc;
4240
4241                         lpmmi = (MINMAXINFO FAR *)lParam;
4242
4243                         /* this message was sent before WM_NCCREATE */
4244                         if (!td) return 1;
4245
4246                         /* Minimum window size is 80x24 */
4247                         rc.left = rc.top = 0;
4248                         rc.right = rc.left + 20 * td->tile_wid + td->size_ow1 + td->size_ow2;
4249                         rc.bottom = rc.top + 3 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
4250
4251                         /* Adjust */
4252                         AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
4253
4254                         /* Save minimum size */
4255                         lpmmi->ptMinTrackSize.x = rc.right - rc.left;
4256                         lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;
4257
4258                         return 0;
4259                 }
4260
4261                 case WM_SIZE:
4262                 {
4263                         uint cols;
4264                         uint rows;
4265                         
4266                         /* this message was sent before WM_NCCREATE */
4267                         if (!td) return 1;
4268
4269                         /* it was sent from inside CreateWindowEx */
4270                         if (!td->w) return 1;
4271
4272                         /* was sent from inside WM_SIZE */
4273                         if (td->size_hack) return 1;
4274
4275                         td->size_hack = TRUE;
4276
4277                         cols = (LOWORD(lParam) - td->size_ow1) / td->tile_wid;
4278                         rows = (HIWORD(lParam) - td->size_oh1) / td->tile_hgt;
4279
4280                         /* New size */
4281                         if ((td->cols != cols) || (td->rows != rows))
4282                         {
4283                                 /* Save old term */
4284                                 term *old_term = Term;
4285
4286                                 /* Save the new size */
4287                                 td->cols = cols;
4288                                 td->rows = rows;
4289
4290                                 /* Activate */
4291                                 Term_activate(&td->t);
4292
4293                                 /* Resize the term */
4294                                 Term_resize(td->cols, td->rows);
4295
4296                                 /* Activate */
4297                                 Term_activate(old_term);
4298
4299                                 /* Redraw later */
4300                                 InvalidateRect(td->w, NULL, TRUE);
4301
4302                                 /* HACK - Redraw all windows */
4303                                 p_ptr->window = 0xFFFFFFFF;
4304                                 window_stuff();
4305                         }
4306
4307                         td->size_hack = FALSE;
4308
4309                         return 0;
4310                 }
4311
4312                 case WM_PAINT:
4313                 {
4314                         BeginPaint(hWnd, &ps);
4315                         if (td) term_data_redraw(td);
4316                         EndPaint(hWnd, &ps);
4317                         return 0;
4318                 }
4319
4320                 case WM_SYSKEYDOWN:
4321                 case WM_KEYDOWN:
4322                 {
4323                         bool mc = FALSE;
4324                         bool ms = FALSE;
4325                         bool ma = FALSE;
4326
4327                         /* Extract the modifiers */
4328                         if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
4329                         if (GetKeyState(VK_SHIFT)   & 0x8000) ms = TRUE;
4330                         if (GetKeyState(VK_MENU)    & 0x8000) ma = TRUE;
4331
4332                         /* Handle "special" keys */
4333                         if (special_key[(byte)(wParam)] || (ma && !ignore_key[(byte)(wParam)]) )
4334                         {
4335                                 /* Begin the macro trigger */
4336                                 Term_keypress(31);
4337
4338                                 /* Send the modifiers */
4339                                 if (mc) Term_keypress('C');
4340                                 if (ms) Term_keypress('S');
4341                                 if (ma) Term_keypress('A');
4342
4343                                 /* Extract "scan code" */
4344                                 i = LOBYTE(HIWORD(lParam));
4345
4346                                 /* Introduce the scan code */
4347                                 Term_keypress('x');
4348
4349                                 /* Encode the hexidecimal scan code */
4350                                 Term_keypress(hexsym[i/16]);
4351                                 Term_keypress(hexsym[i%16]);
4352
4353                                 /* End the macro trigger */
4354                                 Term_keypress(13);
4355
4356                                 return 0;
4357                         }
4358
4359                         break;
4360                 }
4361
4362                 case WM_CHAR:
4363                 {
4364                         Term_keypress(wParam);
4365                         return 0;
4366                 }
4367
4368                 case WM_PALETTECHANGED:
4369                 {
4370                         /* ignore if palette change caused by itself */
4371                         if ((HWND)wParam == hWnd) return FALSE;
4372                         /* otherwise, fall through!!! */
4373                 }
4374
4375                 case WM_QUERYNEWPALETTE:
4376                 {
4377                         if (!paletted) return 0;
4378                         hdc = GetDC(hWnd);
4379                         SelectPalette(hdc, hPal, FALSE);
4380                         i = RealizePalette(hdc);
4381                         /* if any palette entries changed, repaint the window. */
4382                         if (i) InvalidateRect(hWnd, NULL, TRUE);
4383                         ReleaseDC(hWnd, hdc);
4384                         return 0;
4385                 }
4386
4387                 case WM_NCLBUTTONDOWN:
4388                 {
4389
4390 #ifdef HTCLOSE
4391                         if (wParam == HTCLOSE) wParam = HTSYSMENU;
4392 #endif /* HTCLOSE */
4393
4394                         if (wParam == HTSYSMENU)
4395                         {
4396                                 if (td->visible)
4397                                 {
4398                                         td->visible = FALSE;
4399                                         ShowWindow(td->w, SW_HIDE);
4400                                 }
4401
4402                                 return 0;
4403                         }
4404
4405                         break;
4406                 }
4407         }
4408
4409         return DefWindowProc(hWnd, uMsg, wParam, lParam);
4410 }
4411
4412
4413 #ifdef USE_SAVER
4414
4415 #define MOUSE_SENS 40
4416
4417 #ifdef __MWERKS__
4418 LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
4419                                     WPARAM wParam, LPARAM lParam);
4420 LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
4421                                     WPARAM wParam, LPARAM lParam)
4422 #else /* __MWERKS__ */
4423 LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
4424                                             WPARAM wParam, LPARAM lParam)
4425 #endif /* __MWERKS__ */
4426 {
4427         static int iMouse = 0;
4428         static WORD xMouse = 0;
4429         static WORD yMouse = 0;
4430
4431         int dx, dy;
4432
4433
4434         /* Process */
4435         switch (uMsg)
4436         {
4437                 /* XXX XXX XXX */
4438                 case WM_NCCREATE:
4439                 {
4440                         break;
4441                 }
4442
4443                 case WM_SETCURSOR:
4444                 {
4445                         SetCursor(NULL);
4446                         return 0;
4447                 }
4448
4449 #if 0
4450                 case WM_ACTIVATE:
4451                 {
4452                         if (LOWORD(wParam) == WA_INACTIVE) break;
4453
4454                         /* else fall through */
4455                 }
4456 #endif
4457
4458                 case WM_LBUTTONDOWN:
4459                 case WM_MBUTTONDOWN:
4460                 case WM_RBUTTONDOWN:
4461                 case WM_KEYDOWN:
4462                 {
4463                         SendMessage(hWnd, WM_CLOSE, 0, 0);
4464                         return 0;
4465                 }
4466
4467                 case WM_MOUSEMOVE:
4468                 {
4469                         if (iMouse)
4470                         {
4471                                 dx = LOWORD(lParam) - xMouse;
4472                                 dy = HIWORD(lParam) - yMouse;
4473
4474                                 if (dx < 0) dx = -dx;
4475                                 if (dy < 0) dy = -dy;
4476
4477                                 if ((dx > MOUSE_SENS) || (dy > MOUSE_SENS))
4478                                 {
4479                                         SendMessage(hWnd, WM_CLOSE, 0, 0);
4480                                 }
4481                         }
4482
4483                         /* Save last location */
4484                         iMouse = 1;
4485                         xMouse = LOWORD(lParam);
4486                         yMouse = HIWORD(lParam);
4487
4488                         return 0;
4489                 }
4490
4491                 case WM_CLOSE:
4492                 {
4493                         DestroyWindow(hwndSaver);
4494                         hwndSaver = NULL;
4495                         return 0;
4496                 }
4497         }
4498
4499         /* Oops */
4500         return DefWindowProc(hWnd, uMsg, wParam, lParam);
4501 }
4502
4503 #endif /* USE_SAVER */
4504
4505
4506
4507
4508
4509 /*** Temporary Hooks ***/
4510
4511
4512 /*
4513  * Display warning message (see "z-util.c")
4514  */
4515 static void hack_plog(cptr str)
4516 {
4517         /* Give a warning */
4518         if (str)
4519         {
4520 #ifdef JP
4521                 MessageBox(NULL, str, "·Ù¹ð¡ª",
4522                            MB_ICONEXCLAMATION | MB_OK);
4523 #else
4524                 MessageBox(NULL, str, "Warning",
4525                            MB_ICONEXCLAMATION | MB_OK);
4526 #endif
4527
4528         }
4529 }
4530
4531
4532 /*
4533  * Display error message and quit (see "z-util.c")
4534  */
4535 static void hack_quit(cptr str)
4536 {
4537         /* Give a warning */
4538         if (str)
4539         {
4540 #ifdef JP
4541                 MessageBox(NULL, str, "¥¨¥é¡¼¡ª",
4542                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
4543 #else
4544                 MessageBox(NULL, str, "Error",
4545                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
4546 #endif
4547
4548         }
4549
4550         /* Unregister the classes */
4551         UnregisterClass(AppName, hInstance);
4552
4553         /* Destroy the icon */
4554         if (hIcon) DestroyIcon(hIcon);
4555
4556         /* Exit */
4557         exit(0);
4558 }
4559
4560
4561
4562 /*** Various hooks ***/
4563
4564
4565 /*
4566  * Display warning message (see "z-util.c")
4567  */
4568 static void hook_plog(cptr str)
4569 {
4570         /* Warning */
4571         if (str)
4572         {
4573 #ifdef JP
4574                 MessageBox(data[0].w, str, "·Ù¹ð¡ª",
4575                            MB_ICONEXCLAMATION | MB_OK);
4576 #else
4577                 MessageBox(data[0].w, str, "Warning",
4578                            MB_ICONEXCLAMATION | MB_OK);
4579 #endif
4580
4581         }
4582 }
4583
4584
4585 /*
4586  * Display error message and quit (see "z-util.c")
4587  */
4588 static void hook_quit(cptr str)
4589 {
4590         int i;
4591
4592
4593         /* Give a warning */
4594         if (str)
4595         {
4596 #ifdef JP
4597                 MessageBox(data[0].w, str, "¥¨¥é¡¼¡ª",
4598                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
4599 #else
4600                 MessageBox(data[0].w, str, "Error",
4601                            MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
4602 #endif
4603
4604         }
4605
4606
4607         /* Save the preferences */
4608         save_prefs();
4609
4610
4611         /*** Could use 'Term_nuke_win()' XXX XXX XXX */
4612
4613         /* Destroy all windows */
4614         for (i = MAX_TERM_DATA - 1; i >= 0; --i)
4615         {
4616                 term_force_font(&data[i], NULL);
4617                 if (data[i].font_want) string_free(data[i].font_want);
4618                 if (data[i].w) DestroyWindow(data[i].w);
4619                 data[i].w = 0;
4620         }
4621
4622         /* Free the bitmap stuff */
4623 #ifdef USE_GRAPHICS
4624         if (infGraph.hPalette) DeleteObject(infGraph.hPalette);
4625         if (infGraph.hBitmap) DeleteObject(infGraph.hBitmap);
4626
4627 #ifdef USE_TRANSPARENCY
4628         if (infMask.hPalette) DeleteObject(infMask.hPalette);
4629         if (infMask.hBitmap) DeleteObject(infMask.hBitmap);
4630 #endif /* USE_TRANSPARENCY */
4631
4632 #endif /* USE_GRAPHICS */
4633
4634         /*** Free some other stuff ***/
4635
4636         DeleteObject(hbrYellow);
4637
4638         /* bg */
4639         delete_bg();
4640
4641         if (hPal) DeleteObject(hPal);
4642
4643         UnregisterClass(AppName, hInstance);
4644
4645         if (hIcon) DestroyIcon(hIcon);
4646
4647         exit(0);
4648 }
4649
4650
4651
4652 /*** Initialize ***/
4653
4654
4655 /*
4656  * Init some stuff
4657  */
4658 static void init_stuff(void)
4659 {
4660         int i;
4661
4662         char path[1024];
4663
4664
4665         /* Get program name with full path */
4666         GetModuleFileName(hInstance, path, 512);
4667
4668         /* Save the "program name" XXX XXX XXX */
4669         argv0 = path;
4670
4671         /* Get the name of the "*.ini" file */
4672         strcpy(path + strlen(path) - 4, ".INI");
4673
4674         /* Save the the name of the ini-file */
4675         ini_file = string_make(path);
4676
4677         /* Analyze the path */
4678         i = strlen(path);
4679
4680         /* Get the path */
4681         for (; i > 0; i--)
4682         {
4683                 if (path[i] == '\\')
4684                 {
4685                         /* End of path */
4686                         break;
4687                 }
4688         }
4689
4690         /* Add "lib" to the path */
4691         strcpy(path + i + 1, "lib\\");
4692
4693         /* Validate the path */
4694         validate_dir(path, TRUE);
4695
4696         /* Init the file paths */
4697         init_file_paths(path);
4698
4699         /* Hack -- Validate the paths */
4700         validate_dir(ANGBAND_DIR_APEX, FALSE);
4701         validate_dir(ANGBAND_DIR_BONE, FALSE);
4702
4703         /* Allow missing 'edit' directory */
4704         if (!check_dir(ANGBAND_DIR_EDIT))
4705         {
4706                 /* Must have 'data'! */
4707                 validate_dir(ANGBAND_DIR_DATA, TRUE);
4708         }
4709         else
4710         {
4711                 /* Don't need 'data' */
4712                 validate_dir(ANGBAND_DIR_DATA, FALSE);
4713         }
4714
4715         validate_dir(ANGBAND_DIR_FILE, TRUE);
4716         validate_dir(ANGBAND_DIR_HELP, FALSE);
4717         validate_dir(ANGBAND_DIR_INFO, FALSE);
4718         validate_dir(ANGBAND_DIR_PREF, TRUE);
4719         validate_dir(ANGBAND_DIR_SAVE, FALSE);
4720         validate_dir(ANGBAND_DIR_USER, TRUE);
4721         validate_dir(ANGBAND_DIR_XTRA, TRUE);
4722
4723         /* Build the filename */
4724 #ifdef JP
4725         path_build(path, 1024, ANGBAND_DIR_FILE, "news_j.txt");
4726 #else
4727         path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt");
4728 #endif
4729
4730
4731         /* Hack -- Validate the "news.txt" file */
4732         validate_file(path);
4733
4734
4735 #ifndef JP
4736         /* Build the "font" path */
4737         path_build(path, 1024, ANGBAND_DIR_XTRA, "font");
4738
4739         /* Allocate the path */
4740         ANGBAND_DIR_XTRA_FONT = string_make(path);
4741
4742         /* Validate the "font" directory */
4743         validate_dir(ANGBAND_DIR_XTRA_FONT, TRUE);
4744
4745         /* Build the filename */
4746         path_build(path, 1024, ANGBAND_DIR_XTRA_FONT, "8X13.FON");
4747
4748         /* Hack -- Validate the basic font */
4749         validate_file(path);
4750 #endif
4751
4752
4753 #ifdef USE_GRAPHICS
4754
4755         /* Build the "graf" path */
4756         path_build(path, 1024, ANGBAND_DIR_XTRA, "graf");
4757
4758         /* Allocate the path */
4759         ANGBAND_DIR_XTRA_GRAF = string_make(path);
4760
4761         /* Validate the "graf" directory */
4762         validate_dir(ANGBAND_DIR_XTRA_GRAF, TRUE);
4763
4764 #endif /* USE_GRAPHICS */
4765
4766
4767 #ifdef USE_SOUND
4768
4769         /* Build the "sound" path */
4770         path_build(path, 1024, ANGBAND_DIR_XTRA, "sound");
4771
4772         /* Allocate the path */
4773         ANGBAND_DIR_XTRA_SOUND = string_make(path);
4774
4775         /* Validate the "sound" directory */
4776         validate_dir(ANGBAND_DIR_XTRA_SOUND, FALSE);
4777
4778 #endif /* USE_SOUND */
4779
4780 #ifdef USE_MUSIC
4781
4782         /* Build the "music" path */
4783         path_build(path, 1024, ANGBAND_DIR_XTRA, "music");
4784
4785         /* Allocate the path */
4786         ANGBAND_DIR_XTRA_MUSIC = string_make(path);
4787
4788         /* Validate the "music" directory */
4789         validate_dir(ANGBAND_DIR_XTRA_MUSIC, FALSE);
4790
4791 #endif /* USE_MUSIC */
4792
4793         /* Build the "help" path */
4794         path_build(path, 1024, ANGBAND_DIR_XTRA, "help");
4795
4796         /* Allocate the path */
4797         ANGBAND_DIR_XTRA_HELP = string_make(path);
4798
4799         /* Validate the "help" directory */
4800         /* validate_dir(ANGBAND_DIR_XTRA_HELP); */
4801 }
4802
4803
4804 int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
4805                        LPSTR lpCmdLine, int nCmdShow)
4806 {
4807         int i;
4808
4809         WNDCLASS wc;
4810         HDC hdc;
4811         MSG msg;
4812
4813         /* Save globally */
4814         hInstance = hInst;
4815
4816         /* Initialize */
4817         if (hPrevInst == NULL)
4818         {
4819                 wc.style         = CS_CLASSDC;
4820                 wc.lpfnWndProc   = AngbandWndProc;
4821                 wc.cbClsExtra    = 0;
4822                 wc.cbWndExtra    = 4; /* one long pointer to term_data */
4823                 wc.hInstance     = hInst;
4824                 wc.hIcon         = hIcon = LoadIcon(hInst, AppName);
4825                 wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
4826                 wc.hbrBackground = GetStockObject(BLACK_BRUSH);
4827                 wc.lpszMenuName  = AppName;
4828                 wc.lpszClassName = AppName;
4829
4830                 if (!RegisterClass(&wc)) exit(1);
4831
4832                 wc.lpfnWndProc   = AngbandListProc;
4833                 wc.lpszMenuName  = NULL;
4834                 wc.lpszClassName = AngList;
4835
4836                 if (!RegisterClass(&wc)) exit(2);
4837
4838 #ifdef USE_SAVER
4839
4840                 wc.style          = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_DBLCLKS;
4841                 wc.lpfnWndProc    = AngbandSaverProc;
4842                 wc.hCursor        = NULL;
4843                 wc.lpszMenuName   = NULL;
4844                 wc.lpszClassName  = "WindowsScreenSaverClass";
4845
4846                 if (!RegisterClass(&wc)) exit(3);
4847
4848 #endif
4849
4850         }
4851
4852         /* Temporary hooks */
4853         plog_aux = hack_plog;
4854         quit_aux = hack_quit;
4855         core_aux = hack_quit;
4856
4857         /* Prepare the filepaths */
4858         init_stuff();
4859
4860         /* Initialize the keypress analyzer */
4861         for (i = 0; special_key_list[i]; ++i)
4862         {
4863                 special_key[special_key_list[i]] = TRUE;
4864         }
4865         /* Initialize the keypress analyzer */
4866         for (i = 0; ignore_key_list[i]; ++i)
4867         {
4868                 ignore_key[ignore_key_list[i]] = TRUE;
4869         }
4870
4871         /* Determine if display is 16/256/true color */
4872         hdc = GetDC(NULL);
4873         colors16 = (GetDeviceCaps(hdc, BITSPIXEL) == 4);
4874         paletted = ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? TRUE : FALSE);
4875         ReleaseDC(NULL, hdc);
4876
4877         /* Initialize the colors */
4878         for (i = 0; i < 256; i++)
4879         {
4880                 byte rv, gv, bv;
4881
4882                 /* Extract desired values */
4883                 rv = angband_color_table[i][1];
4884                 gv = angband_color_table[i][2];
4885                 bv = angband_color_table[i][3];
4886
4887                 /* Extract the "complex" code */
4888                 win_clr[i] = PALETTERGB(rv, gv, bv);
4889
4890                 /* Save the "simple" code */
4891                 angband_color_table[i][0] = win_pal[i];
4892         }
4893
4894         /* Prepare the windows */
4895         init_windows();
4896
4897         /* bg */
4898         init_bg();
4899
4900         /* Activate hooks */
4901         plog_aux = hook_plog;
4902         quit_aux = hook_quit;
4903         core_aux = hook_quit;
4904
4905         /* Set the system suffix */
4906         ANGBAND_SYS = "win";
4907
4908         /* Set the keyboard suffix */
4909         if (7 != GetKeyboardType(0))
4910                 ANGBAND_KEYBOARD = "0";
4911         else
4912         {
4913                 /* Japanese keyboard */
4914                 switch (GetKeyboardType(1))
4915                 {
4916                 case 0x0D01: case 0x0D02:
4917                 case 0x0D03: case 0x0D04:
4918                 case 0x0D05: case 0x0D06:
4919                         /* NEC PC-98x1 */
4920                         ANGBAND_KEYBOARD = "NEC98";
4921                         break;
4922                 default:
4923                         /* PC/AT */
4924                         ANGBAND_KEYBOARD = "JAPAN";
4925                 }
4926         }
4927
4928
4929         /* Initialize */
4930         init_angband();
4931
4932         /* We are now initialized */
4933         initialized = TRUE;
4934
4935 #ifdef CHUUKEI
4936         if(lpCmdLine[0] == '-'){
4937           switch(lpCmdLine[1])
4938           {
4939           case 'p':
4940             {
4941               if (!lpCmdLine[2]) break;
4942               chuukei_server = TRUE;
4943               if(connect_chuukei_server(&lpCmdLine[2])<0){
4944                 msg_print("connect fail");
4945                 return 0;
4946               }
4947               msg_print("connect");
4948               msg_print(NULL);
4949               break;
4950             }
4951
4952           case 'c':
4953             {
4954               if (!lpCmdLine[2]) break;
4955               chuukei_client = TRUE;
4956               connect_chuukei_server(&lpCmdLine[2]);
4957               play_game(FALSE);
4958               quit(NULL);
4959               return 0;
4960             }
4961           }
4962         }
4963 #endif
4964
4965 #ifdef CHUUKEI
4966         /* Did the user double click on a save file? */
4967         if(!chuukei_server) check_for_save_file(lpCmdLine);
4968 #else
4969         /* Did the user double click on a save file? */
4970         check_for_save_file(lpCmdLine);
4971 #endif
4972
4973         /* Prompt the user */
4974 #ifdef JP
4975         prt("[¥Õ¥¡¥¤¥ë] ¥á¥Ë¥å¡¼¤Î [¿·µ¬] ¤Þ¤¿¤Ï [³«¤¯] ¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£", 23, 8);
4976 #else
4977         prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 17);
4978 #endif
4979
4980         Term_fresh();
4981
4982         /* Process messages forever */
4983         while (GetMessage(&msg, NULL, 0, 0))
4984         {
4985                 TranslateMessage(&msg);
4986                 DispatchMessage(&msg);
4987         }
4988
4989         /* Paranoia */
4990         quit(NULL);
4991
4992         /* Paranoia */
4993         return (0);
4994 }
4995
4996
4997 #endif /* WINDOWS */
4998