OSDN Git Service

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