OSDN Git Service

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