OSDN Git Service

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