1 /* File: main-win.c */
2
3 /* Purpose: Support for Windows Angband */
4
5 /*
6 * Written (2.7.8) by Skirmantas Kligys (kligys@scf.usc.edu)
7 *
8 * Based loosely on "main-mac.c" and "main-xxx.c" and suggestions
9 * by Ben Harrison (benh@voicenet.com).
10 *
11 * Upgrade to Angband 2.7.9v6 by Ben Harrison (benh@voicenet.com),
12 * Ross E Becker (beckerr@cis.ohio-state.edu), and Chris R. Martin
13 * (crm7479@tam2000.tamu.edu).
14 *
15 * Note that the "Windows" version requires several extra files, which
16 * must be placed in various places. These files are distributed in a
17 * special "ext-win.zip" archive, with instructions on where to place
18 * the various files. For example, we require that all font files,
19 * bitmap files, and sound files, be placed into the "lib/xtra/font/",
20 * "/lib/xtra/graf/", and "lib/xtra/sound/" directories, respectively.
21 *
22 * See "h-config.h" for the extraction of the "WINDOWS" flag based
23 * on the "_Windows", "__WINDOWS__", "__WIN32__", "WIN32", "__WINNT__",
24 * or "__NT__" flags. If your compiler uses a different compiler flag,
25 * add it to "h-config.h", or, simply place it in the "Makefile".
26 *
27 *
28 * This file still needs some work, possible problems are indicated by
29 * the string "XXX XXX XXX" in any comment.
30 *
31 * XXX XXX XXX
32 * The "Term_xtra_win_clear()" function should probably do a low-level
33 * clear of the current window, and redraw the borders and other things.
34 *
35 * XXX XXX XXX
36 * The user should be able to select the "bitmap" for a window independant
37 * from the "font", and should be allowed to select any bitmap file which
38 * is strictly smaller than the font file. Currently, bitmap selection
39 * always imitates the font selection unless the "Font" and "Graf" lines
40 * are used in the "ANGBAND.INI" file. This may require the addition
41 * of a menu item for each window to select the bitmaps.
42 *
43 * XXX XXX XXX
44 * The various "warning" messages assume the existance of the "screen.w"
45 * window, I think, and only a few calls actually check for its existance,
46 * this may be okay since "NULL" means "on top of all windows". (?)
47 *
48 * XXX XXX XXX
49 * Special "Windows Help Files" can be placed into "lib/xtra/help/" for
50 * use with the "winhelp.exe" program. These files *may* be available
51 * at the ftp site somewhere.
52 *
53 * XXX XXX XXX
54 * The "prepare menus" command should "gray out" any menu command which
55 * is not allowed at the current time. This will simplify the actual
56 * processing of menu commands, which can assume the command is legal.
57 *
58 * XXX XXX XXX
59 * Remove the old "FontFile" entries from the "*.ini" file, and remove
60 * the entire section about "sounds", after renaming a few sound files.
61 */
62
63
64 #include "c-angband.h"
65
66 #ifdef USE_WIN
67
68 #define MNU_SUPPORT
69
70 /*
71 * Extract the "WIN32" flag from the compiler
72 */
73 #if defined(__WIN32__) || defined(__WINNT__) || defined(__NT__)
74 # ifndef WIN32
75 # define WIN32
76 # endif
77 #endif
78
79 /*
80 * XXX XXX XXX Hack -- broken sound libraries
81 */
82 #ifdef BEN_HACK
83 # undef USE_SOUND
84 #endif
85
86
87 /*
88 * Menu constants -- see "ANGBAND.RC"
89 */
90
91 #define IDM_FILE_NEW 101
92 #define IDM_FILE_OPEN 102
93 #define IDM_FILE_SAVE 103
94 #define IDM_FILE_EXIT 104
95 #define IDM_FILE_QUIT 105
96
97 #define IDM_TEXT_SCREEN 201
98 #define IDM_TEXT_MIRROR 202
99 #define IDM_TEXT_RECALL 203
100 #define IDM_TEXT_CHOICE 204
101 #define IDM_TEXT_TERM_4 205
102 #define IDM_TEXT_TERM_5 206
103 #define IDM_TEXT_TERM_6 207
104 #define IDM_TEXT_TERM_7 208
105
106 #define IDM_WINDOWS_SCREEN 211
107 #define IDM_WINDOWS_MIRROR 212
108 #define IDM_WINDOWS_RECALL 213
109 #define IDM_WINDOWS_CHOICE 214
110 #define IDM_WINDOWS_TERM_4 215
111 #define IDM_WINDOWS_TERM_5 216
112 #define IDM_WINDOWS_TERM_6 217
113 #define IDM_WINDOWS_TERM_7 218
114
115 #define IDM_GRAPHICS_OFF 221
116 #define IDM_GRAPHICS_BIG_TILE 222
117 #define IDM_GRAPHICS_TILESET_1 223
118 #define IDM_GRAPHICS_TILESET_2 224
119 #define IDM_GRAPHICS_TILESET_3 225
120 #define IDM_GRAPHICS_TILESET_4 226
121 #define IDM_GRAPHICS_TILESET_5 227
122 #define IDM_GRAPHICS_TILESET_6 228
123 #define IDM_GRAPHICS_TILESET_7 229
124 #define IDM_GRAPHICS_TILESET_8 230
125
126 #define IDM_OPTIONS_SOUND 301
127 #define IDM_OPTIONS_MOUSE 302
128 #define IDM_OPTIONS_UNUSED 231
129 #define IDM_OPTIONS_SAVER 232
130
131 #define IDM_HELP_GENERAL 901
132 #define IDM_HELP_SPOILERS 902
133 #define IDM_HELP_ABOUT 903
134
135 /*
136 * exclude parts of WINDOWS.H that are not needed
137 */
138 #define NOSOUND /* Sound APIs and definitions */
139 #define NOCOMM /* Comm driver APIs and definitions */
140 #define NOLOGERROR /* LogError() and related definitions */
141 #define NOPROFILER /* Profiler APIs */
142 #define NOLFILEIO /* _l* file I/O routines */
143 #define NOOPENFILE /* OpenFile and related definitions */
144 #define NORESOURCE /* Resource management */
145 #define NOATOM /* Atom management */
146 #define NOLANGUAGE /* Character test routines */
147 #define NOLSTRING /* lstr* string management routines */
148 #define NODBCS /* Double-byte character set routines */
149 #define NOKEYBOARDINFO /* Keyboard driver routines */
150 #define NOCOLOR /* COLOR_* color values */
151 #define NODRAWTEXT /* DrawText() and related definitions */
152 #define NOSCALABLEFONT /* Truetype scalable font support */
153 #define NOMETAFILE /* Metafile support */
154 #define NOSYSTEMPARAMSINFO /* SystemParametersInfo() and SPI_* definitions */
155 #define NODEFERWINDOWPOS /* DeferWindowPos and related definitions */
156 #define NOKEYSTATES /* MK_* message key state flags */
157 #define NOWH /* SetWindowsHook and related WH_* definitions */
158 #define NOCLIPBOARD /* Clipboard APIs and definitions */
159 #define NOICONS /* IDI_* icon IDs */
160 #define NOMDI /* MDI support */
161 #define NOCTLMGR /* Control management and controls */
162 #define NOHELP /* Help support */
163
164 /*
165 * exclude parts of WINDOWS.H that are not needed (Win32)
166 */
167 #define WIN32_LEAN_AND_MEAN
168 #define NONLS /* All NLS defines and routines */
169 #define NOSERVICE /* All Service Controller routines, SERVICE_ equates, etc. */
170 #define NOKANJI /* Kanji support stuff. */
171 #define NOMCX /* Modem Configuration Extensions */
172
173 /*
174 * Include the "windows" support file
175 */
176 #ifndef WIN32_LEAN_AND_MEAN
177 #define WIN32_LEAN_AND_MEAN
178 #endif
179 #ifndef _WINSOCK2API_
180 //#include <winsock2.h>
181 #endif
182
183
184 /*
185 * exclude parts of MMSYSTEM.H that are not needed
186 */
187 #define MMNODRV /* Installable driver support */
188 #define MMNOWAVE /* Waveform support */
189 #define MMNOMIDI /* MIDI support */
190 #define MMNOAUX /* Auxiliary audio support */
191 #define MMNOTIMER /* Timer support */
192 #define MMNOJOY /* Joystick support */
193 #define MMNOMCI /* MCI support */
194 #define MMNOMMIO /* Multimedia file I/O support */
195 #define MMNOMMSYSTEM /* General MMSYSTEM functions */
196
197 /*
198 * Include the ??? files
199 */
200 #include <mmsystem.h>
201 #include <commdlg.h>
202
203 /*
204 * Include the support for loading bitmaps
205 */
206 #ifdef USE_GRAPHICS
207 # include "win/readdib.h"
208 #endif
209
210 /*
211 * Hack -- allow use of the Borg as a screen-saver
212 */
213 #ifdef ALLOW_BORG
214 # define ALLOW_SCRSAVER
215 #endif
216
217 /*
218 * Cannot include "dos.h", so we define some things by hand.
219 */
220 #ifdef WIN32
221 #define INVALID_FILE_NAME (DWORD)0xFFFFFFFF
222 #else /* WIN32 */
223 #define FA_LABEL 0x08 /* Volume label */
224 #define FA_DIREC 0x10 /* Directory */
225 unsigned _cdecl _dos_getfileattr(const char *, unsigned *);
226 #endif /* WIN32 */
227
228 /*
229 * Silliness in WIN32 drawing routine
230 */
231 #ifdef WIN32
232 # define MoveTo(H,X,Y) MoveToEx(H, X, Y, NULL)
233 #endif /* WIN32 */
234
235 /*
236 * Silliness for Windows 95
237 */
238 #ifndef WS_EX_TOOLWINDOW
239 # define WS_EX_TOOLWINDOW 0
240 #endif
241
242 /*
243 * Foreground color bits (hard-coded by DOS)
244 */
245 #define VID_BLACK 0x00
246 #define VID_BLUE 0x01
247 #define VID_GREEN 0x02
248 #define VID_CYAN 0x03
249 #define VID_RED 0x04
250 #define VID_MAGENTA 0x05
251 #define VID_YELLOW 0x06
252 #define VID_WHITE 0x07
253
254 /*
255 * Bright text (hard-coded by DOS)
256 */
257 #define VID_BRIGHT 0x08
258
259 /*
260 * Background color bits (hard-coded by DOS)
261 */
262 #define VUD_BLACK 0x00
263 #define VUD_BLUE 0x10
264 #define VUD_GREEN 0x20
265 #define VUD_CYAN 0x30
266 #define VUD_RED 0x40
267 #define VUD_MAGENTA 0x50
268 #define VUD_YELLOW 0x60
269 #define VUD_WHITE 0x70
270
271 /*
272 * Blinking text (hard-coded by DOS)
273 */
274 #define VUD_BRIGHT 0x80
275
276
277 /*
278 * Forward declare
279 */
280 typedef struct _term_data term_data;
281
282 /*
283 * Extra "term" data
284 *
285 * Note the use of "font_want" and "graf_want" for the names of the
286 * font/graf files requested by the user, and the use of "font_file"
287 * and "graf_file" for the currently active font/graf files.
288 *
289 * The "font_file" and "graf_file" are capitilized, and are of the
290 * form "8X13.FON" and "8X13.BMP", while "font_want" and "graf_want"
291 * can be in almost any form as long as it could be construed as
292 * attempting to represent the name of a font or bitmap or file.
293 */
294 struct _term_data
295 {
296 term t;
297
298 cptr s;
299
300 HWND w;
301
302 #ifdef USE_GRAPHICS
303
304 #endif
305
306 DWORD dwStyle;
307 DWORD dwExStyle;
308
309 uint keys;
310
311 uint rows;
312 uint cols;
313
314 uint pos_x;
315 uint pos_y;
316 uint size_wid;
317 uint size_hgt;
318 uint client_wid;
319 uint client_hgt;
320 uint size_ow1;
321 uint size_oh1;
322 uint size_ow2;
323 uint size_oh2;
324
325 byte visible;
326
327 byte size_hack;
328
329 cptr font_want;
330 cptr graf_want;
331
332 cptr font_file;
333
334 HFONT font_id;
335
336 uint font_wid;
337 uint font_hgt;
338 };
339
340 #ifdef USE_GRAPHICS
341 /*
342 * Flag set once "graphics" has been initialized
343 */
344 static bool can_use_graphics = FALSE;
345
346 /*
347 * The global bitmap
348 */
349 static DIBINIT infGraph;
350
351 /*
352 * The global bitmap mask
353 */
354 static DIBINIT infMask;
355
356 #endif
357 /*
358 * Maximum number of windows XXX XXX XXX XXX
359 */
360 #define MAX_TERM_DATA 8
361
362 /*
363 * An array of term_data's
364 */
365 static term_data win_data[MAX_TERM_DATA];
366
367 /*
368 * Mega-Hack -- global "window creation" pointer
369 */
370 static term_data *td_ptr;
371
372 /*
373 * Even bigger hack than the above -- global edit control handle [grk]
374 */
375 static HWND editmsg;
376 static HWND old_focus = NULL;
377 LRESULT APIENTRY SubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
378 WNDPROC lpfnOldWndProc;
379
380 /*
381 * Various boolean flags
382 */
383 bool game_in_progress = FALSE; /* game in progress */
384 bool initialized = FALSE; /* note when "open"/"new" become valid */
385 bool paletted = FALSE; /* screen paletted, i.e. 256 colors */
386 bool colors16 = FALSE; /* 16 colors screen, don't use RGB() */
387 bool use_mouse = FALSE; /* game accepts mouse */
388
389 /*
390 * Saved instance handle
391 */
392 static HINSTANCE hInstance;
393
394 /*
395 * Yellow brush for the cursor
396 */
397 static HBRUSH hbrYellow;
398
399 /*
400 * Black brush for the chat window edit control
401 */
402 static HBRUSH hbrBlack;
403
404 /*
405 * An icon
406 */
407 static HICON hIcon;
408
409 /*
410 * A palette
411 */
412 static HPALETTE hPal;
413
414 #ifdef ALLOW_SCRSAVER
415
416 /*
417 * The screen saver
418 */
419 static HWND hwndSaver;
420
421 #endif
422
423 /*
424 * Full path to ANGBAND.INI
425 */
426 static cptr ini_file = NULL;
427
428 /*
429 * Name of application
430 */
431 static cptr AppName = "ANGBAND";
432
433 /*
434 * Name of sub-window type
435 */
436 static cptr AngList = "AngList";
437 static int next_graphics = 0;
438 static int loaded_graphics = 0;
439 /*
440 * Directory names
441 */
442 static cptr ANGBAND_DIR_XTRA_FONT;
443 #define ANGBAND_DIR_XTRA_HELP ".\\lib\\text"
444
445 #ifdef USE_SOUND
446
447 /*
448 * Flag set once "sound" has been initialized
449 */
450 static bool can_use_sound = FALSE;
451
452 #endif /* USE_SOUND */
453
454 /*
455 * The Angband color set:
456 * Black, White, Slate, Orange, Red, Blue, Green, Umber
457 * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
458 *
459 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
460 * Note that on B/W machines, all non-zero colors can be white (on black).
461 *
462 * Note that all characters are assumed to be drawn on a black background.
463 * This may require calling "Term_wipe()" before "Term_text()", etc.
464 *
465 * XXX XXX XXX See "main-ibm.c" for a method to allow color editing
466 *
467 * XXX XXX XXX The color codes below were taken from "main-ibm.c".
468 */
469 static COLORREF win_clr[16] =
470 {
471 PALETTERGB(0x00, 0x00, 0x00), /* 0 0 0 Dark */
472 PALETTERGB(0xFF, 0xFF, 0xFF), /* 4 4 4 White */
473 PALETTERGB(0x90, 0x90, 0x90), /* 2 2 2 Slate */
474 PALETTERGB(0xFF, 0x80, 0x00), /* 4 2 0 Orange */
475 PALETTERGB(0xFF, 0x20, 0x20), /* 3 0 0 Red (was 2,0,0) */
476 PALETTERGB(0x20, 0x8D, 0x44), /* 0 2 1 Green */
477 PALETTERGB(0x20, 0x50, 0xC0), /* 0 0 4 Blue */
478 PALETTERGB(0x8D, 0x44, 0x20), /* 2 1 0 Umber */
479 PALETTERGB(0x60, 0x60, 0x60), /* 1 1 1 Lt. Dark */
480 PALETTERGB(0xC0, 0xC0, 0xC0), /* 3 3 3 Lt. Slate */
481 PALETTERGB(0xB0, 0x30, 0xFF), /* 4 0 4 Violet (was 2,0,2) */
482 PALETTERGB(0xEF, 0xDF, 0x40), /* 4 4 0 Yellow */
483 // PALETTERGB(0xFF, 0x70, 0x50), /* 4 0 0 Lt. Red (was 4,1,3) */
484 PALETTERGB(0xFF, 0x80, 0x80), /* 4 0 0 Lt. Red (was 4,1,3) */
485 PALETTERGB(0x30, 0xFF, 0x30), /* 0 4 0 Lt. Green */
486 PALETTERGB(0x30, 0xD0, 0xFF), /* 0 4 4 Lt. Blue */
487 PALETTERGB(0xFF, 0xA8, 0x20) /* 3 2 1 Lt. Umber */
488
489
490 #if 0
491 PALETTERGB(0x00, 0x00, 0x00), /* 0 0 0 Dark */
492 PALETTERGB(0xFF, 0xFF, 0xFF), /* 4 4 4 White */
493 PALETTERGB(0x8D, 0x8D, 0x8D), /* 2 2 2 Slate */
494 PALETTERGB(0xFF, 0x8D, 0x00), /* 4 2 0 Orange */
495 PALETTERGB(0xD7, 0x00, 0x00), /* 3 0 0 Red (was 2,0,0) */
496 PALETTERGB(0x00, 0x8D, 0x44), /* 0 2 1 Green */
497 PALETTERGB(0x00, 0x00, 0xFF), /* 0 0 4 Blue */
498 PALETTERGB(0x8D, 0x44, 0x00), /* 2 1 0 Umber */
499 PALETTERGB(0x54, 0x54, 0x54), /* 1 1 1 Lt. Dark */
500 PALETTERGB(0xD7, 0xD7, 0xD7), /* 3 3 3 Lt. Slate */
501 PALETTERGB(0xFF, 0x00, 0xFF), /* 4 0 4 Violet (was 2,0,2) */
502 PALETTERGB(0xFF, 0xFF, 0x00), /* 4 4 0 Yellow */
503 PALETTERGB(0xFF, 0x44, 0xD7), /* 4 0 0 Lt. Red (was 4,1,3) */
504 PALETTERGB(0x00, 0xFF, 0x00), /* 0 4 0 Lt. Green */
505 PALETTERGB(0x00, 0xFF, 0xFF), /* 0 4 4 Lt. Blue */
506 PALETTERGB(0xD7, 0x8D, 0x44) /* 3 2 1 Lt. Umber */
507 #endif
508 };
509
510
511 /*
512 * Palette indices for 16 colors
513 *
514 * See "main-ibm.c" for original table information
515 *
516 * The entries below are taken from the "color bits" defined above.
517 *
518 * Note that many of the choices below suck, but so do crappy monitors.
519 */
520 static BYTE win_pal[16] =
521 {
522 VID_BLACK, /* Dark */
523 VID_WHITE, /* White */
524 VID_CYAN, /* Slate XXX */
525 VID_RED | VID_BRIGHT, /* Orange XXX */
526 VID_RED, /* Red */
527 VID_GREEN, /* Green */
528 VID_BLUE, /* Blue */
529 VID_YELLOW, /* Umber XXX */
530 VID_BLACK | VID_BRIGHT, /* Light Dark */
531 VID_CYAN | VID_BRIGHT, /* Light Slate XXX */
532 VID_MAGENTA, /* Violet XXX */
533 VID_YELLOW | VID_BRIGHT, /* Yellow */
534 VID_MAGENTA | VID_BRIGHT, /* Light Red XXX */
535 VID_GREEN | VID_BRIGHT, /* Light Green */
536 VID_BLUE | VID_BRIGHT, /* Light Blue */
537 VID_YELLOW /* Light Umber XXX */
538 };
539
540 /* [grk]
541 * A gross hack to allow the client to scroll the dungeon display.
542 * This is required for large graphical tiles where we cant have an
543 * 66x22 tile display except in very high screen resolutions.
544 * When the server supports player recentering this can go.
545 *
546 * When we receive a request to plot a tile at a location, we
547 * shift the x-coordinate by this value. If the resultant
548 * x-coordinate is negative we just ignore it and plot nothing.
549 *
550 * We only need scrolling along the x axis.
551 */
552 static char x_offset = 0;
553
554 /* Hack -- set focus to chat message control */
set_chat_focus(void)555 void set_chat_focus( void )
556 {
557 old_focus = GetFocus();
558 SetFocus(editmsg);
559 }
560
unset_chat_focus(void)561 void unset_chat_focus( void )
562 {
563 /* Set focus back to original window */
564 if(old_focus) SetFocus(old_focus);
565 }
566
set_graphics_next(int mode)567 void set_graphics_next(int mode)
568 {
569 // char buf[1024];
570
571 next_graphics = mode;
572 if (next_graphics != use_graphics)
573 {
574 MessageBox(NULL, "You need to restart MAngband in order for the changes to take effect","MAngband",MB_OK);
575
576 /*
577 save_prefs();
578 */
579
580 /* Access the "graphic" mappings */
581 //sprintf(buf, "%s-%s.prf", (use_graphics ? "graf" : "font"), ANGBAND_SYS);
582
583 /* Load the file */
584 //process_pref_file(buf);
585 }
586 }
587
stretch_chat_ctrl(void)588 void stretch_chat_ctrl( void )
589 {
590 /* Resize the edit control */
591 SetWindowPos(editmsg, 0, 2, win_data[4].client_hgt-21,
592 win_data[4].client_wid-6, 20,
593 SWP_NOZORDER);
594 }
595
win32_window_visible(int i)596 int win32_window_visible(int i)
597 {
598 return (bool)win_data[i].visible;
599 }
600
601 /*
602 * Hack -- given a pathname, point at the filename
603 */
extract_file_name(cptr s)604 static cptr extract_file_name(cptr s)
605 {
606 cptr p;
607
608 /* Start at the end */
609 p = s + strlen(s) - 1;
610
611 /* Back up to divider */
612 while ((p >= s) && (*p != ':') && (*p != '\\')) p--;
613
614 /* Return file name */
615 return (p+1);
616 }
617
618
619
620 /*
621 * Check for existance of a file
622 */
check_file(cptr s)623 static bool check_file(cptr s)
624 {
625 char path[1024];
626
627 #ifdef WIN32
628
629 DWORD attrib;
630
631 #else /* WIN32 */
632
633 unsigned int attrib;
634
635 #endif /* WIN32 */
636
637 /* Copy it */
638 strcpy(path, s);
639
640 #ifdef WIN32
641
642 /* Examine */
643 attrib = GetFileAttributes(path);
644
645 /* Require valid filename */
646 if (attrib == INVALID_FILE_NAME) return (FALSE);
647
648 /* Prohibit directory */
649 if (attrib & FILE_ATTRIBUTE_DIRECTORY) return (FALSE);
650
651 #else /* WIN32 */
652
653 /* Examine and verify */
654 if (_dos_getfileattr(path, &attrib)) return (FALSE);
655
656 /* Prohibit something */
657 if (attrib & FA_LABEL) return (FALSE);
658
659 /* Prohibit directory */
660 if (attrib & FA_DIREC) return (FALSE);
661
662 #endif /* WIN32 */
663
664 /* Success */
665 return (TRUE);
666 }
667
668
669 /*
670 * Check for existance of a directory
671 */
check_dir(cptr s)672 static bool check_dir(cptr s)
673 {
674 int i;
675
676 char path[1024];
677
678 #ifdef WIN32
679
680 DWORD attrib;
681
682 #else /* WIN32 */
683
684 unsigned int attrib;
685
686 #endif /* WIN32 */
687
688 /* Copy it */
689 strcpy(path, s);
690
691 /* Check length */
692 i = strlen(path);
693
694 /* Remove trailing backslash */
695 if (i && (path[i-1] == '\\')) path[--i] = '\0';
696
697 #ifdef WIN32
698
699 /* Examine */
700 attrib = GetFileAttributes(path);
701
702 /* Require valid filename */
703 if (attrib == INVALID_FILE_NAME) return (FALSE);
704
705 /* Require directory */
706 if (!(attrib & FILE_ATTRIBUTE_DIRECTORY)) return (FALSE);
707
708 #else /* WIN32 */
709
710 /* Examine and verify */
711 if (_dos_getfileattr(path, &attrib)) return (FALSE);
712
713 /* Prohibit something */
714 if (attrib & FA_LABEL) return (FALSE);
715
716 /* Require directory */
717 if (!(attrib & FA_DIREC)) return (FALSE);
718
719 #endif /* WIN32 */
720
721 /* Success */
722 return (TRUE);
723 }
724
725
726 /*
727 * Validate a file
728 */
validate_file(cptr s)729 static void validate_file(cptr s)
730 {
731 /* Verify or fail */
732 if (!check_file(s))
733 {
734 quit_fmt("Cannot find required file:\n%s", s);
735 }
736 }
737
738
739 /*
740 * Validate a directory
741 */
validate_dir(cptr s)742 static void validate_dir(cptr s)
743 {
744 /* Verify or fail */
745 if (!check_dir(s))
746 {
747 quit_fmt("Cannot find required directory:\n%s", s);
748 }
749 }
750
751
752 /*
753 * Get the "size" for a window
754 */
term_getsize(term_data * td)755 static void term_getsize(term_data *td)
756 {
757 RECT rc;
758
759 /* Paranoia */
760 if (td->cols < 1) td->cols = 1;
761 if (td->rows < 1) td->rows = 1;
762
763 /* Paranoia */
764 if (conn_state && td == &win_data[0])
765 {
766 /* if (td->cols < Setup.min_col) td->cols = Setup.min_col;
767 if (td->rows < Setup.min_row) td->rows = Setup.min_row;
768 if (td->cols > Setup.max_col + SCREEN_CLIP_X) td->cols = Setup.max_col + SCREEN_CLIP_X;
769 if (td->rows > Setup.max_row + SCREEN_CLIP_Y) td->rows = Setup.max_row + SCREEN_CLIP_Y; */
770 }
771
772 /* Window sizes */
773 td->client_wid = td->cols * td->font_wid + td->size_ow1 + td->size_ow2;
774 td->client_hgt = td->rows * td->font_hgt + td->size_oh1 + td->size_oh2 + 1;
775
776 /* Fake window size */
777 rc.left = rc.top = 0;
778 rc.right = rc.left + td->client_wid;
779 rc.bottom = rc.top + td->client_hgt;
780
781 /* Adjust */
782 AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
783
784 /* Total size */
785 td->size_wid = rc.right - rc.left;
786 td->size_hgt = rc.bottom - rc.top;
787
788 /* See CreateWindowEx */
789 if (!td->w) return;
790
791 /* Extract actual location */
792 GetWindowRect(td->w, &rc);
793
794 /* Save the location */
795 td->pos_x = rc.left;
796 td->pos_y = rc.top;
797 }
798
799
800 /*
801 * Write the "preference" data for single term
802 */
save_prefs_aux(term_data * td,cptr sec_name)803 static void save_prefs_aux(term_data *td, cptr sec_name)
804 {
805 char buf[32];
806
807 RECT rc;
808
809 if (!td->w) return;
810
811 /* Visible (Sub-windows) */
812 if (td != &win_data[0])
813 {
814 //strcpy(buf, td->visible ? "1" : "0");
815 conf_set_int(sec_name, "Visible", td->visible);
816 }
817
818 /* Desired font */
819 if (td->font_file)
820 {
821 /* Short-hand */
822 if (!strncmp(td->font_file, ANGBAND_DIR_XTRA_FONT, strlen(ANGBAND_DIR_XTRA_FONT)))
823 {
824 strcpy(buf, td->font_file + strlen(ANGBAND_DIR_XTRA_FONT) + 1);
825 conf_set_string(sec_name, "Font", buf);
826 }
827 else
828 /* Full path */
829 conf_set_string(sec_name, "Font", td->font_file);
830 }
831
832 /* Bad Hack :( -- since we allow slight overhead, make sure we're in bounds */
833 /* if (td == &win_data[0] && Setup.max_col && !(window_flag[0] & PW_PLAYER_2) && td->cols > Setup.max_col) td->cols = Setup.max_col; // Compact
834 if (td == &win_data[0] && Setup.max_row && !(window_flag[0] & PW_STATUS) && td->rows > Setup.max_row) td->rows = Setup.max_row; // Status line */
835
836 /* Current size (x) */
837 //wsprintf(buf, "%d", td->cols);
838 conf_set_int(sec_name, "Columns", td->cols);
839
840 /* Current size (y) */
841 //wsprintf(buf, "%d", td->rows);
842 conf_set_int(sec_name, "Rows", td->rows);
843
844 /* Acquire position */
845 if (GetWindowRect(td->w, &rc))
846 {
847 /* Current position (x) */
848 //wsprintf(buf, "%d", rc.left);
849 conf_set_int(sec_name, "PositionX", rc.left);
850
851 /* Current position (y) */
852 //wsprintf(buf, "%d", rc.top);
853 conf_set_int(sec_name, "PositionY", rc.top);
854 }
855 }
856
857
858 /*
859 * Write the "preference" data to the .INI file
860 *
861 * We assume that the windows have all been initialized
862 */
save_prefs(void)863 static void save_prefs(void)
864 {
865 #ifdef USE_GRAPHICS
866 conf_set_int("Windows32", "Graphics", next_graphics);
867 #endif
868 #ifdef USE_SOUND
869 conf_set_int("Windows32", "Sound", use_sound);
870 #endif
871 conf_set_int("Windows32", "GameMouse", use_mouse);
872
873 save_prefs_aux(&win_data[0], "Main window");
874
875 /* XXX XXX XXX XXX */
876
877 save_prefs_aux(&win_data[1], "Mirror window");
878
879 save_prefs_aux(&win_data[2], "Recall window");
880
881 save_prefs_aux(&win_data[3], "Choice window");
882
883 save_prefs_aux(&win_data[4], "Term-4 window");
884
885 save_prefs_aux(&win_data[5], "Term-5 window");
886
887 save_prefs_aux(&win_data[6], "Term-6 window");
888
889 save_prefs_aux(&win_data[7], "Term-7 window");
890 }
891
892
893 /*
894 * Load preference for a single term
895 */
load_prefs_aux(term_data * td,cptr sec_name)896 static void load_prefs_aux(term_data *td, cptr sec_name)
897 {
898 char tmp[128];
899
900 /* Visibility (Sub-window) */
901 if (td != &win_data[0])
902 {
903 /* Extract visibility */
904 td->visible = (conf_get_int(sec_name, "Visible", td->visible) != 0);
905 }
906
907 /* Desired font, with default */
908 strcpy(tmp, conf_get_string(sec_name, "Font", "8X13.FON"));
909 td->font_want = string_make(extract_file_name(tmp));
910
911 /* Desired graf, with default */
912 //strcpy(tmp, conf_get_string(sec_name, "Graf", GFXBMP[use_graphics]));
913 //td->graf_want = string_make(extract_file_name(tmp));
914
915 /* Window size */
916 td->cols = conf_get_int(sec_name, "Columns", td->cols);
917 td->rows = conf_get_int(sec_name, "Rows", td->rows);
918
919 /* Window position */
920 td->pos_x = conf_get_int(sec_name, "PositionX", td->pos_x);
921 td->pos_y = conf_get_int(sec_name, "PositionY", td->pos_y);
922 }
923
924 /*
925 * Load the preferences from the .INI file
926 */
load_prefs(void)927 static void load_prefs(void)
928 {
929 char buffer[20] = {'\0'};
930 DWORD bufferLen = sizeof(buffer);
931
932 #ifdef USE_GRAPHICS
933 /* Extract the "use_graphics" flag */
934 loaded_graphics = conf_get_int("Windows32", "Graphics", 0);
935 set_graphics(loaded_graphics);
936 set_graphics_next(loaded_graphics);
937 #endif
938
939 #ifdef USE_SOUND
940 /* Extract the "use_sound" flag */
941 use_sound = (conf_get_int("Windows32", "Sound", 0) != 0);
942 #endif
943
944 /* Extract the "use_mouse" flag */
945 use_mouse = (conf_get_int("Windows32", "GameMouse", 1) == 1);
946
947 /* Load window prefs */
948 load_prefs_aux(&win_data[0], "Main window");
949
950 /* XXX XXX XXX XXX */
951
952 load_prefs_aux(&win_data[1], "Mirror window");
953
954 load_prefs_aux(&win_data[2], "Recall window");
955
956 load_prefs_aux(&win_data[3], "Choice window");
957
958 load_prefs_aux(&win_data[4], "Term-4 window");
959
960 load_prefs_aux(&win_data[5], "Term-5 window");
961
962 load_prefs_aux(&win_data[6], "Term-6 window");
963
964 load_prefs_aux(&win_data[7], "Term-7 window");
965
966 /* Pull nick/pass */
967 my_strcpy(nick, conf_get_string("MAngband", "nick", "PLAYER"), MAX_CHARS);
968 my_strcpy(pass, conf_get_string("MAngband", "pass", "passwd"), MAX_CHARS);
969 my_strcpy(server_name, conf_get_string("MAngband", "host", ""), MAX_CHARS);
970
971 /* Pull username from Windows */
972 if ( GetUserName(buffer, &bufferLen) ) {
973 /* Cut */
974 buffer[16] = '\0';
975 strcpy(real_name, buffer);
976
977 }
978 else
979 {
980 /* XXX Default real name */
981 strcpy(real_name, "PLAYER");
982 }
983 }
984
985
986 /*
987 * Create the new global palette based on the bitmap palette
988 * (if any) from the given bitmap xxx, and the standard 16
989 * entry palette derived from "win_clr[]" which is used for
990 * the basic 16 Angband colors.
991 *
992 * This function is never called before all windows are ready.
993 */
new_palette(void)994 static int new_palette(void)
995 {
996 HPALETTE hBmPal;
997 HPALETTE hNewPal;
998 HDC hdc;
999 int i, nEntries;
1000 int pLogPalSize;
1001 int lppeSize;
1002 LPLOGPALETTE pLogPal;
1003 LPPALETTEENTRY lppe;
1004
1005
1006 /* Cannot handle palettes */
1007 if (!paletted) return (TRUE);
1008
1009 /* No palette */
1010 hBmPal = NULL;
1011
1012 /* No bitmap */
1013 lppeSize = 0;
1014 lppe = NULL;
1015 nEntries = 0;
1016
1017 #ifdef USE_GRAPHICS
1018
1019 /* Check the bitmap palette */
1020 hBmPal = infGraph.hPalette;
1021
1022 /* Use the bitmap */
1023 if (hBmPal)
1024 {
1025 lppeSize = 256*sizeof(PALETTEENTRY);
1026 lppe = (LPPALETTEENTRY)ralloc(lppeSize);
1027 nEntries = GetPaletteEntries(hBmPal, 0, 255, lppe);
1028 if (nEntries == 0) {
1029 plog("Corrupted bitmap palette");
1030 FREE(lppe);
1031 return (FALSE);
1032 }
1033 else if (nEntries > 220) {
1034 plog("Bitmap must have no more than 220 colors");
1035 FREE(lppe);
1036 return (FALSE);
1037 }
1038 }
1039
1040 #endif
1041
1042 /* Size of palette */
1043 pLogPalSize = sizeof(LOGPALETTE) + (16+nEntries)*sizeof(PALETTEENTRY);
1044
1045 /* Allocate palette */
1046 pLogPal = (LPLOGPALETTE)ralloc(pLogPalSize);
1047
1048 /* Version */
1049 pLogPal->palVersion = 0x300;
1050
1051 /* Make room for bitmap and normal data */
1052 pLogPal->palNumEntries = nEntries + 16;
1053
1054 /* Save the bitmap data */
1055 for (i = 0; i < nEntries; i++)
1056 {
1057 pLogPal->palPalEntry[i] = lppe[i];
1058 }
1059
1060 /* Save the normal data */
1061 for (i = 0; i < 16; i++)
1062 {
1063 LPPALETTEENTRY p;
1064
1065 /* Access the entry */
1066 p = &(pLogPal->palPalEntry[i+nEntries]);
1067
1068 /* Save the colors */
1069 p->peRed = GetRValue(win_clr[i]);
1070 p->peGreen = GetGValue(win_clr[i]);
1071 p->peBlue = GetBValue(win_clr[i]);
1072
1073 /* Save the flags */
1074 p->peFlags = PC_NOCOLLAPSE;
1075 }
1076
1077 /* Free something */
1078 if (lppe) FREE(lppe);
1079
1080 /* Create a new palette, or fail */
1081 hNewPal = CreatePalette(pLogPal);
1082 if (!hNewPal) quit("Cannot create palette");
1083
1084 /* Free the palette */
1085 FREE(pLogPal);
1086
1087
1088 hdc = GetDC(win_data[0].w);
1089 SelectPalette(hdc, hNewPal, 0);
1090 i = RealizePalette(hdc);
1091 ReleaseDC(win_data[0].w, hdc);
1092 if (i == 0) quit("Cannot realize palette");
1093
1094 /* Check windows */
1095 for (i = 1; i < MAX_TERM_DATA; i++)
1096 {
1097 hdc = GetDC(win_data[i].w);
1098 SelectPalette(hdc, hNewPal, 0);
1099 ReleaseDC(win_data[i].w, hdc);
1100 }
1101
1102 /* Delete old palette */
1103 if (hPal) DeleteObject(hPal);
1104
1105 /* Save new palette */
1106 hPal = hNewPal;
1107
1108 /* Success */
1109 return (TRUE);
1110 }
1111
1112
1113 #ifdef USE_SOUND
1114 /*
1115 * Initialize sound
1116 */
init_sound(void)1117 static bool init_sound(void)
1118 {
1119 /* Initialize once */
1120 if (!can_use_sound)
1121 {
1122 /* Load the prefs */
1123 load_sound_prefs();
1124
1125 /* Sound available */
1126 can_use_sound = TRUE;
1127 }
1128
1129 /* Result */
1130 return (can_use_sound);
1131 }
1132 #endif /* USE_SOUND */
1133
1134
1135 /*
1136 * Resize a window
1137 */
term_window_resize(term_data * td)1138 static void term_window_resize(term_data *td)
1139 {
1140
1141 /* Require window */
1142 if (!td->w) return;
1143
1144 /* Resize the window */
1145 SetWindowPos(td->w, 0, 0, 0,
1146 td->size_wid, td->size_hgt,
1147 SWP_NOMOVE | SWP_NOZORDER);
1148
1149 /* Redraw later */
1150 InvalidateRect(td->w, NULL, TRUE);
1151 }
1152
1153 /*
1154 * See if any other term is already using font_file
1155 */
term_font_inuse(term_data * td)1156 static bool term_font_inuse(term_data* td)
1157 {
1158 int i;
1159 bool used = FALSE;
1160
1161 /* Scan windows */
1162 for (i = 0; i < MAX_TERM_DATA; i++)
1163 {
1164 /* Check "screen" */
1165 if ((td != &win_data[i]) &&
1166 (win_data[i].font_file) &&
1167 (streq(win_data[i].font_file, td->font_file)))
1168 {
1169 used = TRUE;
1170 break;
1171 }
1172 }
1173 return used;
1174 }
1175
1176 /*
1177 * Force the use of a new "font file" for a term_data
1178 *
1179 * This function may be called before the "window" is ready
1180 *
1181 * This function returns zero only if everything succeeds.
1182 */
term_force_font(term_data * td,cptr name)1183 static errr term_force_font(term_data *td, cptr name)
1184 {
1185 int i;
1186
1187 int wid, hgt;
1188
1189 cptr s;
1190
1191 char base[16];
1192
1193 char base_font[16];
1194
1195 char buf[1024];
1196
1197
1198 /* Forget the old font (if needed) */
1199 if (td->font_id) DeleteObject(td->font_id);
1200
1201 /* Forget old font */
1202 if (td->font_file)
1203 {
1204 bool used = term_font_inuse(td);
1205
1206 /* Remove unused font resources */
1207 if (!used) RemoveFontResource(td->font_file);
1208
1209 /* Free the old name */
1210 string_free(td->font_file);
1211
1212 /* Forget it */
1213 td->font_file = NULL;
1214 }
1215
1216
1217 /* No name given */
1218 if (!name) return (1);
1219
1220 /* Extract the base name (with suffix) */
1221 s = extract_file_name(name);
1222
1223 /* Extract font width */
1224 wid = atoi(s);
1225
1226 /* Default font height */
1227 hgt = 0;
1228
1229 /* Copy, capitalize, remove suffix, extract width */
1230 for (i = 0; (i < 16 - 1) && s[i] && (s[i] != '.'); i++)
1231 {
1232 /* Capitalize */
1233 base[i] = FORCEUPPER(s[i]);
1234
1235 /* Extract "hgt" when found */
1236 if (base[i] == 'X') hgt = atoi(s+i+1);
1237 }
1238
1239 /* Terminate */
1240 base[i] = '\0';
1241
1242
1243 /* Build base_font */
1244 strcpy(base_font, base);
1245 strcat(base_font, ".FON");
1246
1247
1248 /* Access the font file */
1249 path_build(buf, 1024, ANGBAND_DIR_XTRA_FONT, base_font);
1250
1251
1252 /* Verify file */
1253 if (!check_file(buf)) return (1);
1254
1255
1256 /* Save new font name */
1257 td->font_file = string_make(buf);
1258
1259 /* If this font is used for the first time */
1260 if (!term_font_inuse(td))
1261 {
1262 /* Load the new font or quit */
1263 if (!AddFontResource(buf))
1264 {
1265 quit_fmt("Font file corrupted:\n%s", buf);
1266 }
1267 }
1268
1269 /* Create the font XXX XXX XXX Note use of "base" */
1270 td->font_id = CreateFont(hgt, wid, 0, 0, FW_DONTCARE, 0, 0, 0,
1271 ANSI_CHARSET, OUT_DEFAULT_PRECIS,
1272 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
1273 FIXED_PITCH | FF_DONTCARE, base);
1274
1275
1276 /* Hack -- Unknown size */
1277 if (!wid || !hgt)
1278 {
1279 HDC hdcDesktop;
1280 HFONT hfOld;
1281 TEXTMETRIC tm;
1282
1283 /* all this trouble to get the cell size */
1284 hdcDesktop = GetDC(HWND_DESKTOP);
1285 hfOld = SelectObject(hdcDesktop, td->font_id);
1286 GetTextMetrics(hdcDesktop, &tm);
1287 SelectObject(hdcDesktop, hfOld);
1288 ReleaseDC(HWND_DESKTOP, hdcDesktop);
1289
1290 /* Font size info */
1291 wid = tm.tmAveCharWidth;
1292 hgt = tm.tmHeight;
1293 }
1294
1295 /* Save the size info */
1296 td->font_wid = wid;
1297 td->font_hgt = hgt;
1298
1299
1300 /* Analyze the font */
1301 term_getsize(td);
1302
1303 /* Resize the window */
1304 term_window_resize(td);
1305
1306 /* Success */
1307 return (0);
1308 }
1309
1310
1311 #ifdef USE_GRAPHICS
1312
1313 /*
1314 * Force the use of a new "graf file" for a term_data
1315 *
1316 * This function is never called before the windows are ready
1317 *
1318 * This function returns zero only if everything succeeds.
1319 */
term_force_graf(term_data * td,graphics_mode * gm)1320 static errr term_force_graf(term_data *td, graphics_mode *gm)
1321 {
1322 int i, is_png = 0;
1323
1324 int wid, hgt;
1325
1326 cptr s;
1327
1328 char buf[1024];
1329
1330 /* No name */
1331 if (!gm->file) return (1);
1332
1333 /* Extract the base name (with suffix) */
1334 s = gm->file;
1335
1336 /* Extract font width */
1337 wid = gm->cell_width;
1338
1339 /* Default font height */
1340 hgt = gm->cell_height;
1341
1342 /* Require actual sizes */
1343 if (!wid || !hgt) return (1);
1344
1345 /* Check if we need PNG loader */
1346 if (isuffix(s, ".png")) is_png = TRUE;
1347
1348 /* Access the graf file */
1349 path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, gm->file);
1350
1351 /* Verify file */
1352 if (!check_file(buf)) return (1);
1353
1354 /* Note: PNG loader will extract the mask from the alpha
1355 * channel, or assume colorkey is at pixel0,0 */
1356 if (is_png)
1357 {
1358 /* Load the png or quit */
1359 if (!ReadDIB2_PNG(td->w, buf, &infGraph, &infMask, FALSE))
1360 {
1361 quit_fmt("Cannot read file '%s'", buf);
1362 }
1363 }
1364 else
1365 {
1366 /* Load the bitmap or quit */
1367 if (!ReadDIB(td->w, buf, &infGraph))
1368 {
1369 quit_fmt("Bitmap corrupted:\n%s", buf);
1370 }
1371
1372 /* Load mask, if appropriate */
1373 if (!STRZERO(gm->mask))
1374 {
1375 /* Access the mask file */
1376 path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, gm->mask);
1377
1378 /* Load the bitmap or quit */
1379 if (!ReadDIB(win_data[0].w, buf, &infMask))
1380 {
1381 quit_fmt("Cannot read bitmap mask file '%s'", buf);
1382 }
1383 }
1384 }
1385 /* Save the new sizes */
1386 infGraph.CellWidth = wid;
1387 infGraph.CellHeight = hgt;
1388
1389 /* Copy the picture from the bitmap to the window */
1390 // BitBlt(hdc, x2, y2, w1, h1, hdcSrc, x1, y1, SRCCOPY);
1391
1392 /* Activate a palette */
1393 if (!new_palette())
1394 {
1395 /* Free bitmap XXX XXX XXX */
1396
1397 /* Oops */
1398 plog("Cannot activate palette!");
1399 return (FALSE);
1400 }
1401 /* Graphics available */
1402 can_use_graphics = use_graphics;
1403
1404 /* Success */
1405 return (can_use_graphics);
1406 }
1407
1408 #endif
1409
1410
1411 /*
1412 * Allow the user to change the font (and graf) for this window.
1413 *
1414 * XXX XXX XXX This is only called for non-graphic windows
1415 */
term_change_font(term_data * td)1416 static void term_change_font(term_data *td)
1417 {
1418 OPENFILENAME ofn;
1419 TCHAR fullFileName[2048];
1420 char tmp[1024] = "";
1421
1422 /* Extract a default if possible */
1423 if (td->font_file) strcpy(tmp, td->font_file);
1424
1425 /* No default? Let's build it */
1426 if (STRZERO(tmp))
1427 {
1428 strnfmt(tmp, 1024, "%s%s", ANGBAND_DIR_XTRA_FONT, "\\*.fon");
1429 }
1430
1431 /* Resolve absolute path */
1432 if (_fullpath(fullFileName, tmp, 2048) == NULL)
1433 {
1434 /* Complete and utter despair... */
1435 strcpy(fullFileName, "\\*.fon");
1436 }
1437
1438 /* Ask for a choice */
1439 memset(&ofn, 0, sizeof(ofn));
1440 ofn.lStructSize = sizeof(ofn);
1441 ofn.hwndOwner = win_data[0].w;
1442 ofn.lpstrFilter = "Font Files (*.fon)\0*.fon\0";
1443 ofn.nFilterIndex = 1;
1444 ofn.lpstrFile = fullFileName;
1445 ofn.nMaxFile = 128;
1446 ofn.lpstrInitialDir = NULL;
1447
1448 ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
1449 ofn.lpstrDefExt = "fon";
1450
1451 /* Force choice if legal */
1452 if (GetOpenFileName(&ofn))
1453 {
1454 /* Force the font */
1455 if (term_force_font(td, fullFileName))
1456 {
1457 /* Oops */
1458 (void)term_force_font(td, "8X13.FON");
1459 }
1460 }
1461 }
1462
1463
1464 #ifdef USE_GRAPHICS
1465
1466 #if 0 /* Manual change disabled */
1467 /*
1468 * Allow the user to change the graf (and font) for a window
1469 *
1470 * XXX XXX XXX This is only called for graphic windows, and
1471 * changes the font and the bitmap for the window, and is
1472 * only called if "use_graphics" is true.
1473 */
1474 static void term_change_bitmap(term_data *td)
1475 {
1476 OPENFILENAME ofn;
1477
1478 char tmp[128] = "";
1479
1480 /* Ask for a choice */
1481 memset(&ofn, 0, sizeof(ofn));
1482 ofn.lStructSize = sizeof(ofn);
1483 ofn.hwndOwner = win_data[0].w;
1484 ofn.lpstrFilter = "Bitmap Files (*.bmp)\0*.bmp\0";
1485 ofn.nFilterIndex = 1;
1486 ofn.lpstrFile = tmp;
1487 ofn.nMaxFile = 128;
1488 ofn.lpstrInitialDir = ANGBAND_DIR_XTRA_GRAF;
1489 ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
1490 ofn.lpstrDefExt = "bmp";
1491
1492 /* Force choice if legal */
1493 if (GetOpenFileName(&ofn))
1494 {
1495 /* XXX XXX XXX */
1496
1497 /* Force the requested font and bitmap */
1498 if (
1499 term_force_graf(td, tmp))
1500 {
1501 graphics_mode *gm;
1502 /* Force the "standard" font */
1503 //(void)term_force_font(td, "8X13.FON");
1504
1505 /* Force the "standard" bitmap */
1506 gm = get_graphics_mode((byte)use_graphics);
1507 (void)term_force_graf(td, gm ? gm->file : "");
1508 }
1509 }
1510 }
1511 #endif
1512
1513 #endif
1514
1515
1516 /*
1517 * Hack -- redraw a term_data
1518 */
term_data_redraw(term_data * td)1519 static void term_data_redraw(term_data *td)
1520 {
1521 /* Activate the term */
1522 Term_activate(&td->t);
1523
1524 /* Redraw the contents */
1525 Term_redraw();
1526
1527 /* Restore the term */
1528 Term_activate(term_screen);
1529 }
1530 /*
1531 * Hack -- resize term_data
1532 */
term_data_resize(term_data * td,bool redraw)1533 static void term_data_resize(term_data *td, bool redraw)
1534 {
1535 /* Activate the term */
1536 Term_activate(&td->t);
1537
1538 /* Redraw the contents */
1539 if (redraw) Term_redraw();
1540
1541 /* Resize! */
1542 Term_resize(td->cols, td->rows);
1543
1544 /* Restore the term */
1545 Term_activate(term_screen);
1546 }
1547
1548
1549
1550
1551
1552 /*** Function hooks needed by "Term" ***/
1553
1554 /*
1555 * Interact with the User
1556 */
Term_user_win(int n)1557 static errr Term_user_win(int n)
1558 {
1559 /* Success */
1560 return (0);
1561 }
1562
1563
1564 /*
1565 * React to global changes
1566 */
Term_xtra_win_react(void)1567 static errr Term_xtra_win_react(void)
1568 {
1569 int i;
1570
1571 /* I added this USE_GRAPHICS because we lost color support as well. -GP */
1572 #ifdef USE_GRAPHICS
1573 static old_use_graphics = FALSE;
1574
1575
1576 /* XXX XXX XXX Check "color_table[]" */
1577
1578
1579 /* Simple color */
1580 if (colors16)
1581 {
1582 /* Save the default colors */
1583 for (i = 0; i < 16; i++)
1584 {
1585 /* Simply accept the desired colors */
1586 win_pal[i] = color_table[i][0];
1587 }
1588 }
1589
1590 /* Complex color */
1591 else
1592 {
1593 COLORREF code;
1594
1595 byte rv, gv, bv;
1596
1597 bool change = FALSE;
1598
1599 /* Save the default colors */
1600 for (i = 0; i < 16; i++)
1601 {
1602 /* Extract desired values */
1603 rv = color_table[i][1];
1604 gv = color_table[i][2];
1605 bv = color_table[i][3];
1606
1607 /* Extract a full color code */
1608 code = PALETTERGB(rv, gv, bv);
1609
1610 /* Activate changes */
1611 if (win_clr[i] != code)
1612 {
1613 /* Note the change */
1614 change = TRUE;
1615
1616 /* Apply the desired color */
1617 win_clr[i] = code;
1618 }
1619 }
1620
1621 /* Activate the palette if needed */
1622 if (change) (void)new_palette();
1623 }
1624 #endif /* no color support -gp */
1625
1626 #ifdef USE_SOUND
1627 /* Initialize sound (if needed) */
1628 if (use_sound && !init_sound())
1629 {
1630 /* Warning */
1631 plog("Cannot initialize sound!");
1632
1633 /* Cannot enable */
1634 use_sound = FALSE;
1635 }
1636 #endif /* USE_SOUND */
1637
1638 #ifdef USE_GRAPHICS
1639
1640 /* XXX XXX XXX Check "use_graphics" */
1641 if (use_graphics && !old_use_graphics)
1642 {
1643 /*
1644 * Code for reacting to graphical changes.
1645 */
1646 }
1647
1648 /* Remember */
1649 old_use_graphics = use_graphics;
1650
1651 #endif
1652
1653
1654 /* Clean up windows */
1655 for (i = 0; i < MAX_TERM_DATA; i++)
1656 {
1657 term *old = Term;
1658
1659 term_data *td = &win_data[i];
1660
1661 /* Skip non-changes XXX XXX XXX */
1662 if ((td->cols == td->t.wid) && (td->rows == td->t.hgt)) continue;
1663
1664 /* Activate */
1665 Term_activate(&td->t);
1666
1667
1668 InvalidateRect(td->w, NULL, TRUE);
1669 /* Hack -- Resize the term */
1670 //Term_resize(td->cols, td->rows);
1671
1672 /* Redraw the contents */
1673 Term_redraw();
1674
1675 /* Restore */
1676 Term_activate(old);
1677 }
1678
1679
1680 /* Success */
1681 return (0);
1682 }
1683
1684
1685 /*
1686 * Process at least one event
1687 */
Term_xtra_win_event(int v)1688 static errr Term_xtra_win_event(int v)
1689 {
1690 MSG msg;
1691
1692 /* Wait for an event */
1693 if (v)
1694 {
1695 /* Block */
1696 if (GetMessage(&msg, NULL, 0, 0))
1697 {
1698 TranslateMessage(&msg);
1699 DispatchMessage(&msg);
1700 }
1701 }
1702
1703 /* Check for an event */
1704 else
1705 {
1706 /* Check */
1707 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1708 {
1709 TranslateMessage(&msg);
1710 DispatchMessage(&msg);
1711 }
1712 }
1713
1714 /* Success */
1715 return 0;
1716 }
1717
1718
1719 /*
1720 * Process all pending events
1721 */
Term_xtra_win_flush(void)1722 static errr Term_xtra_win_flush(void)
1723 {
1724 MSG msg;
1725
1726 /* Process all pending events */
1727 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1728 {
1729 TranslateMessage(&msg);
1730 DispatchMessage(&msg);
1731 }
1732
1733 /* Success */
1734 return (0);
1735 }
1736
1737
1738 /*
1739 * Hack -- clear the screen
1740 *
1741 * XXX XXX XXX Make this more efficient
1742 */
Term_xtra_win_clear(void)1743 static errr Term_xtra_win_clear(void)
1744 {
1745 term_data *td = (term_data*)(Term->data);
1746
1747 HDC hdc;
1748 RECT rc;
1749
1750 /* Rectangle to erase */
1751 rc.left = td->size_ow1;
1752 rc.right = rc.left + td->cols * td->font_wid;
1753 rc.top = td->size_oh1;
1754 rc.bottom = rc.top + td->rows * td->font_hgt;
1755
1756 /* Erase it */
1757 hdc = GetDC(td->w);
1758 SetBkColor(hdc, RGB(0, 0, 0));
1759 SelectObject(hdc, td->font_id);
1760 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
1761 ReleaseDC(td->w, hdc);
1762
1763 /* Success */
1764 return 0;
1765 }
1766
1767
1768 /*
1769 * Hack -- make a noise
1770 */
Term_xtra_win_noise(void)1771 static errr Term_xtra_win_noise(void)
1772 {
1773 MessageBeep(MB_ICONASTERISK);
1774 return (0);
1775 }
1776
1777
1778 /*
1779 * Hack -- make a sound
1780 */
Term_xtra_win_sound(int v)1781 static errr Term_xtra_win_sound(int v)
1782 {
1783 #ifdef USE_SOUND
1784 char buf[MSG_LEN];
1785 int s = sound_count(v);
1786
1787 /* Illegal sound */
1788 if (!s) return (-1);
1789
1790 /* Random sample */
1791 s = randint0(s);
1792
1793 /* Build the path */
1794 path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_SOUND, sound_file[v][s]);
1795
1796 /* Play the sound */
1797 return PlaySound(buf, NULL, SND_FILENAME | SND_ASYNC);
1798 #else
1799 /* Oops */
1800 return (1);
1801 #endif /* USE_SOUND */
1802 }
1803
1804
1805 /*
1806 * Delay for "x" milliseconds
1807 */
Term_xtra_win_delay(int v)1808 int Term_xtra_win_delay(int v)
1809 {
1810
1811 #ifdef WIN32
1812
1813 /* Sleep */
1814 Sleep(v);
1815
1816 #else /* WIN32 */
1817
1818 DWORD t;
1819 MSG msg;
1820
1821 /* Final count */
1822 t = GetTickCount() + v;
1823
1824 /* Wait for it */
1825 while (GetTickCount() < t)
1826 {
1827 /* Handle messages */
1828 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1829 {
1830 TranslateMessage(&msg);
1831 DispatchMessage(&msg);
1832 }
1833 }
1834
1835 #endif /* WIN32 */
1836
1837 /* Success */
1838 return (0);
1839 }
1840
1841
1842 /*
1843 * Do a "special thing"
1844 */
Term_xtra_win(int n,int v)1845 static errr Term_xtra_win(int n, int v)
1846 {
1847 /* Handle a subset of the legal requests */
1848 switch (n)
1849 {
1850 /* Make a bell sound */
1851 case TERM_XTRA_NOISE:
1852 return (Term_xtra_win_noise());
1853
1854 /* Make a special sound */
1855 case TERM_XTRA_SOUND:
1856 return (Term_xtra_win_sound(v));
1857
1858 /* Process random events */
1859 case TERM_XTRA_BORED:
1860 return (Term_xtra_win_event(0));
1861
1862 /* Process an event */
1863 case TERM_XTRA_EVENT:
1864 return (Term_xtra_win_event(v));
1865
1866 /* Flush all events */
1867 case TERM_XTRA_FLUSH:
1868 return (Term_xtra_win_flush());
1869
1870 /* Clear the screen */
1871 case TERM_XTRA_CLEAR:
1872 return (Term_xtra_win_clear());
1873
1874 /* React to global changes */
1875 case TERM_XTRA_REACT:
1876 return (v == 0 ? Term_xtra_win_react() : 0);
1877
1878 /* Delay for some milliseconds */
1879 case TERM_XTRA_DELAY:
1880 return (Term_xtra_win_delay(v));
1881 }
1882
1883 /* Oops */
1884 return 1;
1885 }
1886
1887
1888
1889 /*
1890 * Low level graphics (Assumes valid input).
1891 *
1892 * Erase a "block" of "n" characters starting at (x,y).
1893 */
Term_wipe_win(int x,int y,int n)1894 static errr Term_wipe_win(int x, int y, int n)
1895 {
1896 term_data *td = (term_data*)(Term->data);
1897
1898 HDC hdc;
1899 RECT rc;
1900
1901 #ifdef USE_GRAPHICS
1902 /* [grk] Client-side scrolling support
1903 * This is a kludge see declaration of x_offset */
1904 // if(td == &win_data[0]){
1905 // x = x - x_offset;
1906 // if(x+n<13) return 0;
1907 // if(x<13){
1908 // n = n + (x-13);
1909 // x = 13;
1910 // }
1911 // }
1912 #endif
1913 /* Rectangle to erase in client coords */
1914 rc.left = x * td->font_wid + td->size_ow1;
1915 rc.right = rc.left + n * td->font_wid;
1916 rc.top = y * td->font_hgt + td->size_oh1;
1917 rc.bottom = rc.top + td->font_hgt;
1918
1919 hdc = GetDC(td->w);
1920 SetBkColor(hdc, RGB(0, 0, 0));
1921 SelectObject(hdc, td->font_id);
1922 ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
1923 ReleaseDC(td->w, hdc);
1924
1925 /* Success */
1926 return 0;
1927 }
1928
1929
1930 /*
1931 * Low level graphics (Assumes valid input).
1932 * Draw a "cursor" at (x,y), using a "yellow box".
1933 */
Term_curs_win(int x,int y)1934 static errr Term_curs_win(int x, int y)
1935 {
1936 term_data *td = (term_data*)(Term->data);
1937
1938 RECT rc;
1939 HDC hdc;
1940
1941 /* Frame the grid */
1942 rc.left = x * td->font_wid + td->size_ow1;
1943 rc.right = rc.left + td->font_wid;
1944 rc.top = y * td->font_hgt + td->size_oh1;
1945 rc.bottom = rc.top + td->font_hgt;
1946
1947 /* Cursor is done as a yellow "box" */
1948 hdc = GetDC(win_data[0].w);
1949 FrameRect(hdc, &rc, hbrYellow);
1950 ReleaseDC(win_data[0].w, hdc);
1951
1952 /* Success */
1953 return 0;
1954 }
1955
1956
1957 /*
1958 * Low level graphics. Assumes valid input.
1959 * Draw a "special" attr/char at the given location.
1960 *
1961 * XXX XXX XXX We use the "Term_pict_win()" function for "graphic" data,
1962 * which are encoded by setting the "high-bits" of both the "attr" and
1963 * the "char" data. We use the "attr" to represent the "row" of the main
1964 * bitmap, and the "char" to represent the "col" of the main bitmap. The
1965 * use of this function is induced by the "higher_pict" flag.
1966 *
1967 * If we are called for anything but the "screen" window, or if the global
1968 * "use_graphics" flag is off, we simply "wipe" the given grid.
1969 */
1970 // static errr Term_pict_win(int x, int y, byte a, char c)
Term_pict_win(int x,int y,int n,const byte * ap,const char * cp,const byte * tap,const char * tcp)1971 static errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
1972 {
1973 term_data *td = (term_data*)(Term->data);
1974
1975 #ifdef USE_GRAPHICS
1976
1977 HDC hdc;
1978 HDC hdcSrc;
1979 HDC hdcMask;
1980 HBITMAP hbmSrcOld;
1981 int row, col;
1982 int i;
1983 int x1, y1, w1, h1;
1984 int x2, y2, w2, h2;
1985 int x3, y3;
1986 graphics_mode *gm;
1987
1988 /* Paranoia -- handle weird requests */
1989 if (!use_graphics)
1990 {
1991 /* First, erase the grid */
1992 return (Term_wipe_win(x, y, 1));
1993 }
1994
1995 gm = get_graphics_mode((byte)use_graphics);
1996
1997 Term_wipe_win(x, y, n);
1998
1999 #ifdef USE_GRAPHICS
2000 /* [grk] Client-side scrolling support
2001 * This is a kludge see declaration of x_offset */
2002 // if(td == &win_data[0]){
2003 // x = x - x_offset;
2004 // if(x<13) return 0;
2005 // }
2006 #endif
2007
2008 /* Extract picture info */
2009 // row = ((int)ap & 0x7F);
2010 // col = ((int)cp & 0x7F);
2011
2012 /* Size of bitmap cell */
2013 w1 = infGraph.CellWidth;
2014 h1 = infGraph.CellHeight;
2015
2016 /* Location of bitmap cell */
2017 // x1 = col * w1;
2018 // y1 = row * h1;
2019
2020 /* Size of window cell */
2021 w2 = td->font_wid;
2022 h2 = td->font_hgt;
2023
2024 /* Location of window cell */
2025 x2 = x * w2 + td->size_ow1;
2026 y2 = y * h2 + td->size_oh1;
2027
2028 /* Info */
2029 hdc = GetDC(td->w);
2030
2031 /* More info */
2032 hdcSrc = CreateCompatibleDC(hdc);
2033 hbmSrcOld = SelectObject(hdcSrc, infGraph.hBitmap);
2034
2035 if (gm->transparent)
2036 {
2037 hdcMask = CreateCompatibleDC(hdc);
2038 SelectObject(hdcMask, infMask.hBitmap);
2039 }
2040 else
2041 {
2042 hdcMask = NULL;
2043 }
2044
2045 /* Draw attr/char pairs */
2046 for (i = 0; i < n; i++, x2 += w2)
2047 {
2048 byte a = ap[i];
2049 char c = cp[i];
2050
2051 /* Extract picture */
2052 int row = (a & 0x7F);
2053 int col = (c & 0x7F);
2054
2055 /* Location of bitmap cell */
2056 x1 = col * w1;
2057 y1 = row * h1;
2058
2059 if (gm->transparent)
2060 {
2061 x3 = (tcp[i] & 0x7F) * w1;
2062 y3 = (tap[i] & 0x7F) * h1;
2063
2064 /* Perfect size */
2065 if ((w1 == w2) && (h1 == h2))
2066 {
2067 /* Copy the terrain picture from the bitmap to the window */
2068 BitBlt(hdc, x2, y2, w2, h2, hdcSrc, x3, y3, SRCCOPY);
2069
2070 /* Only draw if terrain and overlay are different */
2071 if ((x1 != x3) || (y1 != y3))
2072 {
2073 /* Mask out the tile */
2074 BitBlt(hdc, x2, y2, w2, h2, hdcMask, x1, y1, SRCAND);
2075
2076 /* Draw the tile */
2077 BitBlt(hdc, x2, y2, w2, h2, hdcSrc, x1, y1, SRCPAINT);
2078 }
2079 }
2080
2081 /* Need to stretch */
2082 else
2083 {
2084 /* Set the correct mode for stretching the tiles */
2085 SetStretchBltMode(hdc, COLORONCOLOR);
2086
2087 /* Copy the terrain picture from the bitmap to the window */
2088 StretchBlt(hdc, x2, y2, w2, h2, hdcSrc, x3, y3, w1, h1, SRCCOPY);
2089
2090 /* Only draw if terrain and overlay are different */
2091 if ((x1 != x3) || (y1 != y3))
2092 {
2093 /* Mask out the tile */
2094 StretchBlt(hdc, x2, y2, w2, h2, hdcMask, x1, y1, w1, h1, SRCAND);
2095
2096 /* Draw the tile */
2097 StretchBlt(hdc, x2, y2, w2, h2, hdcSrc, x1, y1, w1, h1, SRCPAINT);
2098 }
2099 }
2100 }
2101 else
2102 {
2103 /* Perfect size */
2104 if ((w1 == w2) && (h1 == h2))
2105 {
2106 /* Copy the picture from the bitmap to the window */
2107 BitBlt(hdc, x2, y2, w2, h2, hdcSrc, x1, y1, SRCCOPY);
2108 }
2109
2110 /* Need to stretch */
2111 else
2112 {
2113 /* Set the correct mode for stretching the tiles */
2114 SetStretchBltMode(hdc, COLORONCOLOR);
2115
2116 /* Copy the picture from the bitmap to the window */
2117 StretchBlt(hdc, x2, y2, w2, h2, hdcSrc, x1, y1, w1, h1, SRCCOPY);
2118 }
2119 }
2120 }
2121
2122 /* Release */
2123 SelectObject(hdcSrc, hbmSrcOld);
2124 DeleteDC(hdcSrc);
2125
2126 if (gm->transparent)
2127 {
2128 /* Release */
2129 SelectObject(hdcMask, hbmSrcOld);
2130 DeleteDC(hdcMask);
2131 }
2132
2133 /* Release */
2134 ReleaseDC(td->w, hdc);
2135
2136 #else
2137
2138 /* Just erase this grid */
2139 return (Term_wipe_win(x, y, 1));
2140
2141 #endif
2142
2143 /* Success */
2144 return 0;
2145 }
2146
2147
2148 /*
2149 * Low level graphics. Assumes valid input.
2150 * Draw several ("n") chars, with an attr, at a given location.
2151 *
2152 * All "graphic" data is handled by "Term_pict_win()", above.
2153 *
2154 * XXX XXX XXX Note that this function assumes the font is monospaced.
2155 *
2156 * XXX XXX XXX One would think there is a more efficient method for
2157 * telling a window what color it should be using to draw with, but
2158 * perhaps simply changing it every time is not too inefficient.
2159 */
Term_text_win(int x,int y,int n,byte a,const char * s)2160 static errr Term_text_win(int x, int y, int n, byte a, const char *s)
2161 {
2162 term_data *td = (term_data*)(Term->data);
2163 RECT rc;
2164 HDC hdc;
2165
2166 #ifdef USE_GRAPHICS
2167 /* [grk] Client-side scrolling support
2168 * This is a kludge see declaration of x_offset */
2169 // if(td == &win_data[0] && (y!=0) ){
2170 // if(x>13){
2171 // x = x - x_offset;
2172 // if(x<13) return 0;
2173 // }
2174 // }
2175 #endif
2176
2177 /* Location */
2178 rc.left = x * td->font_wid + td->size_ow1;
2179 rc.right = rc.left + n * td->font_wid;
2180 rc.top = y * td->font_hgt + td->size_oh1;
2181 rc.bottom = rc.top + td->font_hgt;
2182
2183 /* Acquire DC */
2184 hdc = GetDC(td->w);
2185
2186 /* Background color */
2187 SetBkColor(hdc, RGB(0, 0, 0));
2188
2189 /* Foreground color */
2190 if (colors16)
2191 {
2192 SetTextColor(hdc, PALETTEINDEX(win_pal[a&0x0F]));
2193 }
2194 else
2195 {
2196 SetTextColor(hdc, win_clr[a&0x0F]);
2197 }
2198
2199 /* Use the font */
2200 SelectObject(hdc, td->font_id);
2201
2202 /* Dump the text */
2203 ExtTextOut(hdc, rc.left, rc.top, ETO_OPAQUE | ETO_CLIPPED, &rc,
2204 s, n, NULL);
2205
2206 /* Release DC */
2207 ReleaseDC(td->w, hdc);
2208
2209 /* Success */
2210 return 0;
2211 }
2212
2213
2214 /*** Other routines ***/
2215
2216
2217 /*
2218 * Create and initialize a "term_data" given a title
2219 */
term_data_link(term_data * td)2220 static void term_data_link(term_data *td)
2221 {
2222 term *t = &td->t;
2223
2224 /* Initialize the term */
2225 term_init(t, td->cols, td->rows, td->keys);
2226
2227 /* Use a "software" cursor */
2228 t->soft_cursor = TRUE;
2229
2230 /* Use "Term_pict" for "graphic" data */
2231 t->higher_pict = TRUE;
2232
2233 /* Erase with "white space" */
2234 t->attr_blank = TERM_WHITE;
2235 t->char_blank = ' ';
2236
2237 /* Prepare the template hooks */
2238 t->user_hook = Term_user_win;
2239 t->xtra_hook = Term_xtra_win;
2240 t->wipe_hook = Term_wipe_win;
2241 t->curs_hook = Term_curs_win;
2242 t->pict_hook = Term_pict_win;
2243 t->text_hook = Term_text_win;
2244
2245 /* Remember where we came from */
2246 t->data = (vptr)(td);
2247 }
2248
2249
2250 /*
2251 * Create the windows
2252 *
2253 * First, instantiate the "default" values, then read the "ini_file"
2254 * to over-ride selected values, then create the windows, and fonts.
2255 *
2256 * XXX XXX XXX Need to work on the default window positions
2257 *
2258 * Must use SW_SHOW not SW_SHOWNA, since on 256 color display
2259 * must make active to realize the palette. (?)
2260 */
init_windows(void)2261 static void init_windows(void)
2262 {
2263 int i;
2264 static char version[20];
2265 term_data *td;
2266 HFONT editfont;
2267
2268 /* Main window */
2269 td = &win_data[0];
2270 WIPE(td, term_data);
2271
2272 sprintf(version, "Mangband %d.%d.%d",
2273 CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_PATCH);
2274 td->s = version;
2275 td->keys = 1024;
2276 td->rows = 24;
2277 td->cols = 80;
2278 td->visible = TRUE;
2279 td->size_ow1 = 2;
2280 td->size_ow2 = 2;
2281 td->size_oh1 = 2;
2282 td->size_oh2 = 2;
2283 td->pos_x = 0;
2284 td->pos_y = 0;
2285
2286 /* Sub-windows */
2287 for (i = 1; i < MAX_TERM_DATA; i++)
2288 {
2289 /* Mirror window */
2290 td = &win_data[i];
2291 WIPE(td, term_data);
2292 td->s = ang_term_name[i];
2293 td->keys = 16;
2294 td->rows = 24;
2295 td->cols = 80;
2296 td->visible = TRUE;
2297 td->size_ow1 = 1;
2298 td->size_ow2 = 1;
2299 td->size_oh1 = 1;
2300 /* Hack - give term4 space for edit control [grk] */
2301 if(i!=4) td->size_oh2 = 1;
2302 else td->size_oh2 = 30;
2303 td->pos_x = 0;
2304 td->pos_y = 0;
2305 }
2306
2307
2308 /* Load .INI preferences */
2309 load_prefs();
2310
2311
2312 /* Need these before term_getsize gets called */
2313 win_data[0].dwStyle = (WS_OVERLAPPED | WS_SYSMENU | WS_THICKFRAME |
2314 WS_MINIMIZEBOX | WS_CAPTION | WS_VISIBLE);
2315 win_data[0].dwExStyle = 0;
2316
2317 /* Windows */
2318 for (i = 1; i < MAX_TERM_DATA; i++)
2319 {
2320 win_data[i].dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU);
2321 win_data[i].dwExStyle = (WS_EX_TOOLWINDOW);
2322 }
2323
2324
2325 /* Windows */
2326 for (i = 0; i < MAX_TERM_DATA; i++)
2327 {
2328 if (term_force_font(&win_data[i], win_data[i].font_want))
2329 {
2330 (void)term_force_font(&win_data[i], "8X13.FON");
2331 }
2332 }
2333
2334
2335 /* Screen window */
2336 td_ptr = &win_data[0];
2337 td_ptr->w = CreateWindowEx(td_ptr->dwExStyle, AppName,
2338 td_ptr->s, td_ptr->dwStyle,
2339 td_ptr->pos_x, td_ptr->pos_y,
2340 td_ptr->size_wid, td_ptr->size_hgt,
2341 HWND_DESKTOP, NULL, hInstance, NULL);
2342 if (!td_ptr->w) quit("Failed to create Angband window");
2343 td_ptr = NULL;
2344 term_data_link(&win_data[0]);
2345 ang_term[0] = &win_data[0].t;
2346
2347 /* Windows */
2348 for (i = 1; i < MAX_TERM_DATA; i++)
2349 {
2350 td_ptr = &win_data[i];
2351 td_ptr->w = CreateWindowEx(td_ptr->dwExStyle, AngList,
2352 td_ptr->s, td_ptr->dwStyle,
2353 td_ptr->pos_x, td_ptr->pos_y,
2354 td_ptr->size_wid, td_ptr->size_hgt,
2355 HWND_DESKTOP, NULL, hInstance, NULL);
2356 if (!td_ptr->w) quit("Failed to create sub-window");
2357 if (td_ptr->visible)
2358 {
2359 td_ptr->size_hack = TRUE;
2360 ShowWindow(td_ptr->w, SW_SHOW);
2361 td_ptr->size_hack = FALSE;
2362 }
2363 td_ptr = NULL;
2364 term_data_link(&win_data[i]);
2365 ang_term[i] = &win_data[i].t;
2366 }
2367
2368 /* hack [grk] */
2369 editmsg = CreateWindowEx(WS_EX_STATICEDGE,"EDIT",NULL,WS_CHILD|ES_AUTOHSCROLL|ES_OEMCONVERT|WS_VISIBLE,
2370 2,win_data[4].client_hgt-24,win_data[4].client_wid-8,20,win_data[4].w,NULL,hInstance,NULL);
2371 editfont=CreateFont(16,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH,"Arial");
2372 SendMessage(editmsg, WM_SETFONT, (int)editfont, (int)NULL );
2373 stretch_chat_ctrl();
2374
2375 SendMessage(editmsg, EM_LIMITTEXT, 590, 0L);
2376 lpfnOldWndProc = (WNDPROC)SetWindowLongPtr(editmsg, GWL_WNDPROC, (DWORD) SubClassFunc);
2377
2378 /* Activate the screen window */
2379 SetActiveWindow(win_data[0].w);
2380
2381 /* Bring main screen back to top */
2382 SetWindowPos(win_data[0].w, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2383
2384
2385 #ifdef USE_GRAPHICS
2386
2387 /* Handle "graphics" mode */
2388 if (use_graphics)
2389 {
2390 /* XXX XXX XXX Force the "standard" bitmap */
2391 graphics_mode *gm = get_graphics_mode((byte)use_graphics);
2392
2393 (void)term_force_graf(&win_data[0], gm);
2394 }
2395
2396 #endif
2397
2398 #ifdef USE_SOUND
2399 /* Handle sound module */
2400 Term_xtra_win_react();
2401 #endif
2402
2403 /* New palette XXX XXX XXX */
2404 (void)new_palette();
2405
2406
2407 /* Create a "brush" for drawing the "cursor" */
2408 hbrYellow = CreateSolidBrush(win_clr[TERM_YELLOW]);
2409
2410 /* Create a "brush" for drawing the chat window edit control background */
2411 hbrBlack = CreateSolidBrush(0);
2412
2413 /* Process pending messages */
2414 (void)Term_xtra_win_flush();
2415 }
2416
2417
has_addr_aux(cptr pmsgbuf,int mode,char * addrbuf,size_t addrmax,size_t * addrlen)2418 static char* has_addr_aux(cptr pmsgbuf, int mode, char* addrbuf, size_t addrmax, size_t* addrlen)
2419 {
2420 int offset,breakpoint,nicklen;
2421 char * startmsg;
2422 char search_for = ':';
2423 offset = 0;
2424 if (mode == 1)
2425 {
2426 search_for = ' ';
2427 if (pmsgbuf[0] != '#')
2428 {
2429 *addrlen = 0;
2430 return pmsgbuf;
2431 }
2432 }
2433 for (startmsg = pmsgbuf; *startmsg ; startmsg++ ) {
2434 if( *startmsg==search_for ) break;
2435 };
2436 if( *startmsg && (startmsg-pmsgbuf<addrmax) ) {
2437 strncpy(addrbuf,pmsgbuf,(startmsg-pmsgbuf)+1);
2438 nicklen=strlen(addrbuf);
2439 startmsg+=1;
2440 while (*startmsg == ' ') startmsg+=1;
2441 } else {
2442 startmsg=pmsgbuf;
2443 nicklen=0;
2444 };
2445 *addrlen = nicklen;
2446 return startmsg;
2447 }
has_addr(cptr msg,char * addrbuf,size_t addrmax,size_t * addrlen)2448 static char* has_addr(cptr msg, char* addrbuf, size_t addrmax, size_t* addrlen)
2449 {
2450 char *r;
2451 /* Check channel */
2452 r = has_addr_aux(msg, 1, addrbuf, addrmax, addrlen);
2453 if (*addrlen > 0) return r;
2454
2455 /* Check privmsg */
2456 r = has_addr_aux(msg, 0, addrbuf, addrmax, addrlen);
2457 if (*addrlen > 0) return r;
2458
2459 /* OK, got nothing */
2460 *addrlen = 0;
2461 return msg;
2462 }
2463
2464 /* hack - edit control subclass [grk] */
SubClassFunc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)2465 LRESULT APIENTRY SubClassFunc( HWND hWnd,
2466 UINT Message,
2467 WPARAM wParam,
2468 LPARAM lParam)
2469 {
2470 char pmsgbuf[1000]; /* overkill */
2471 char pmsg[MSG_LEN + 2];
2472 char nickbuf[30];
2473
2474 /* Allow ESCAPE to return focus to main window. */
2475 if( Message == WM_KEYDOWN ) {
2476 if( wParam == VK_ESCAPE ){
2477 unset_chat_focus();
2478 return 0;
2479 }
2480 if (wParam == 33) { /* PGUP */
2481 cmd_chat_cycle(-1);
2482 return 0;
2483 }
2484 if (wParam == 34) { /* PGDN */
2485 cmd_chat_cycle(+1);
2486 return 0;
2487 }
2488 }
2489
2490 if ( Message == WM_CHAR ) {
2491 /* Is this RETURN ? */
2492 if( wParam == 13 || wParam == 10000) {
2493 int CUTOFF=0;
2494 int msglen=0;
2495 memset(nickbuf,0,22);
2496
2497 /* Get the controls text and send it */
2498 msglen = GetWindowText(editmsg, pmsgbuf, 999);
2499
2500 /* Send the text in chunks of CUTOFF characters,
2501 or nearest break before CUTOFF chars */
2502
2503 if( msglen == 0 ){
2504 unset_chat_focus();
2505 return 0;
2506 }
2507 /* Max message length depends on our nick (known)
2508 * and recepient nick (unknown, assume max length) */
2509 CUTOFF = MSG_LEN - strlen(nick) - 3; /* 3 is for decorative symbols */
2510 CUTOFF -= (MAX_NAME_LEN+1); /* +1 for ':' symbol in private messages */
2511 /*RLS*/
2512 if( msglen < CUTOFF ){
2513 send_msg(pmsgbuf);
2514 } else{
2515 int offset,breakpoint,nicklen;
2516 char * startmsg;
2517 offset = 0;
2518
2519 /* see if this was a privmsg, if so, pull off the nick */
2520
2521 startmsg = has_addr(pmsgbuf, nickbuf, 29, &nicklen);
2522
2523 /* now deal with what's left */
2524
2525 while(msglen>0){
2526 memset(pmsg,0,MSG_LEN);
2527
2528 if(msglen<CUTOFF){
2529 breakpoint=msglen;
2530 } else{
2531 /* try to find a breaking char */
2532 for(breakpoint=CUTOFF; breakpoint>0; breakpoint--) {
2533 if( startmsg[offset+breakpoint] == ' ' ) break;
2534 if( startmsg[offset+breakpoint] == ',' ) break;
2535 if( startmsg[offset+breakpoint] == '.' ) break;
2536 if( startmsg[offset+breakpoint] == ';' ) break;
2537 };
2538 if(!breakpoint) breakpoint=CUTOFF; /* nope */
2539 }
2540
2541 /* if we pulled off a nick above, prepend it. */
2542 if(nicklen) strncpy(pmsg,nickbuf,nicklen);
2543
2544 /* stash in this part of the msg */
2545 strncat(pmsg, startmsg+offset, breakpoint);
2546 msglen -= breakpoint;
2547 offset += breakpoint;
2548 send_msg(pmsg);
2549 //Net_flush();
2550 }
2551 }
2552
2553 /* Clear the message box */
2554 pmsgbuf[0] = 0;
2555 SetWindowText(editmsg, pmsgbuf);
2556 unset_chat_focus();
2557 return 0;
2558 }
2559 }
2560
2561 return CallWindowProc(lpfnOldWndProc, hWnd, Message, wParam, lParam);
2562 }
2563
2564
2565 /*
2566 * Hack -- disables new and open from file menu
2567 */
disable_start(void)2568 static void disable_start(void)
2569 {
2570 HMENU hm = GetMenu(win_data[0].w);
2571
2572 EnableMenuItem(hm, IDM_FILE_NEW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2573 EnableMenuItem(hm, IDM_FILE_OPEN, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2574 }
2575
2576
2577 /*
2578 * Prepare the menus
2579 *
2580 * XXX XXX XXX See the updated "main-mac.c" for a much nicer
2581 * system, basically, you explicitly disable any menu option
2582 * which the user should not be allowed to use, and then you
2583 * do not have to do any checking when processing the menu.
2584 */
setup_menus(void)2585 static void setup_menus(void)
2586 {
2587 int i;
2588
2589 HMENU hm = GetMenu(win_data[0].w);
2590 #ifdef MNU_SUPPORT
2591 /* Save player */
2592 EnableMenuItem(hm, IDM_FILE_SAVE,
2593 MF_BYCOMMAND | MF_ENABLED | MF_GRAYED);
2594
2595
2596 /* Exit with save */
2597 EnableMenuItem(hm, IDM_FILE_EXIT,
2598 MF_BYCOMMAND | MF_ENABLED | MF_GRAYED);
2599
2600
2601 /* Window font options */
2602 for (i = 1; i < MAX_TERM_DATA; i++)
2603 {
2604 /* Window font */
2605 EnableMenuItem(hm, IDM_TEXT_SCREEN + i,
2606 MF_BYCOMMAND | (win_data[i].visible ? MF_ENABLED : MF_DISABLED | MF_GRAYED));
2607 }
2608
2609 /* Window options */
2610 for (i = 1; i < MAX_TERM_DATA; i++)
2611 {
2612 /* Window */
2613 CheckMenuItem(hm, IDM_WINDOWS_SCREEN + i,
2614 MF_BYCOMMAND | (win_data[i].visible ? MF_CHECKED : MF_UNCHECKED));
2615 }
2616 #endif
2617 #ifdef USE_GRAPHICS
2618 /* Item "Graphics - Off" */
2619 CheckMenuItem(hm, IDM_GRAPHICS_OFF,
2620 MF_BYCOMMAND | (!next_graphics ? MF_CHECKED : MF_UNCHECKED));
2621
2622 /* Item "Graphics - Tileset N" */
2623 for (i = 0; i < 8; i++)
2624 {
2625 /* Replace "Tileset N" string with actual tileset name */
2626 if ((1 + i) <= get_num_graphics_modes())
2627 {
2628 graphics_mode *gm = get_graphics_mode((byte)(1 + i));
2629 MENUITEMINFO menuitem = { sizeof(MENUITEMINFO) };
2630 GetMenuItemInfo(hm, IDM_GRAPHICS_TILESET_1 + i, FALSE, &menuitem);
2631 menuitem.fMask = MIIM_TYPE | MIIM_DATA;
2632 menuitem.dwTypeData = gm->menuname;
2633 SetMenuItemInfo(hm, IDM_GRAPHICS_TILESET_1 + i, FALSE, &menuitem);
2634 }
2635
2636 /* Item "Graphics - Tileset N" */
2637 CheckMenuItem(hm, IDM_GRAPHICS_TILESET_1 + i,
2638 MF_BYCOMMAND | (next_graphics == 1 + i ? MF_CHECKED : MF_UNCHECKED));
2639
2640 /* XXX Delete unused menu entries */
2641 if ((1 + i) > get_num_graphics_modes())
2642 RemoveMenu(hm, IDM_GRAPHICS_TILESET_1 + i, MF_BYCOMMAND);
2643 }
2644
2645 /* Item "Graphics - Respect Tile Size?" */
2646 CheckMenuItem(hm, IDM_GRAPHICS_BIG_TILE,
2647 MF_BYCOMMAND | (big_tile ? MF_CHECKED : MF_UNCHECKED));
2648 #endif
2649 #ifdef USE_SOUND
2650 /* Item "Sound" */
2651 CheckMenuItem(hm, IDM_OPTIONS_SOUND,
2652 MF_BYCOMMAND | (use_sound ? MF_CHECKED : MF_UNCHECKED));
2653 #endif
2654
2655 /* Item "Mouse" */
2656 CheckMenuItem(hm, IDM_OPTIONS_MOUSE,
2657 MF_BYCOMMAND | (use_mouse ? MF_CHECKED : MF_UNCHECKED));
2658
2659 #ifdef BEN_HACK
2660 /* Item "Colors 16" */
2661 EnableMenuItem(hm, IDM_OPTIONS_UNUSED,
2662 MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2663 #endif
2664
2665 #ifndef ALLOW_SCRSAVER
2666 /* Item "Run as Screensaver" */
2667 EnableMenuItem(hm, IDM_OPTIONS_SAVER,
2668 MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
2669 #endif
2670
2671 }
2672
2673
2674 /*
2675 * Check for double clicked (or dragged) savefile
2676 *
2677 * Apparently, Windows copies the entire filename into the first
2678 * piece of the "command line string". Perhaps we should extract
2679 * the "basename" of that filename and append it to the "save" dir.
2680 */
check_for_save_file(LPSTR cmd_line)2681 static void check_for_save_file(LPSTR cmd_line)
2682 {
2683 char *s, *p;
2684
2685 /* First arg */
2686 s = cmd_line;
2687
2688 /* Second arg */
2689 p = strchr(s, ' ');
2690
2691 /* Tokenize, advance */
2692 if (p) *p++ = '\0';
2693
2694 /* No args */
2695 if (!*s) return;
2696
2697 /* More stuff moved to server -GP
2698 // Extract filename
2699 strcat(savefile, s);
2700
2701 // Validate the file
2702 validate_file(savefile);
2703 */
2704 /* Game in progress */
2705 game_in_progress = TRUE;
2706
2707 /* No restarting */
2708 disable_start();
2709
2710 /* Play game */
2711 /* play_game(FALSE); -changed to network call -GP */
2712 }
2713
dDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)2714 BOOL CALLBACK dDialogProc(
2715 HWND hwndDlg, // handle to dialog box
2716 UINT uMsg, // message
2717 WPARAM wParam, // first message parameter
2718 LPARAM lParam // second message parameter
2719 )
2720 {
2721 switch( uMsg ){
2722 case WM_COMMAND:
2723 EndDialog(hwndDlg,0);
2724 }
2725 return 0;
2726 }
2727
2728 /*
2729 * Process a menu command
2730 */
process_menus(WORD wCmd)2731 static void process_menus(WORD wCmd)
2732 {
2733 #ifdef MNU_SUPPORT
2734 int i;
2735
2736 /* Analyze */
2737 switch (wCmd)
2738 {
2739 /* Save and Exit */
2740 case IDM_FILE_EXIT:
2741 {
2742 quit(NULL);
2743 break;
2744 }
2745
2746
2747 case IDM_TEXT_SCREEN:
2748 {
2749
2750 #ifdef USE_GRAPHICS
2751 /* XXX XXX XXX */
2752 //if (use_graphics)
2753 //{
2754 // term_change_bitmap(&win_data[0]);
2755 // break;
2756 //}
2757 #endif
2758
2759 term_change_font(&win_data[0]);
2760 break;
2761 }
2762
2763 /* Window fonts */
2764 case IDM_TEXT_MIRROR:
2765 case IDM_TEXT_RECALL:
2766 case IDM_TEXT_CHOICE:
2767 case IDM_TEXT_TERM_4:
2768 case IDM_TEXT_TERM_5:
2769 case IDM_TEXT_TERM_6:
2770 case IDM_TEXT_TERM_7:
2771 {
2772 i = wCmd - IDM_TEXT_SCREEN;
2773
2774 if ((i < 0) || (i >= MAX_TERM_DATA)) break;
2775
2776 term_change_font(&win_data[i]);
2777
2778 break;
2779 }
2780
2781 /* Window visibility */
2782 case IDM_WINDOWS_MIRROR:
2783 case IDM_WINDOWS_RECALL:
2784 case IDM_WINDOWS_CHOICE:
2785 case IDM_WINDOWS_TERM_4:
2786 case IDM_WINDOWS_TERM_5:
2787 case IDM_WINDOWS_TERM_6:
2788 case IDM_WINDOWS_TERM_7:
2789 {
2790 i = wCmd - IDM_WINDOWS_SCREEN;
2791
2792 if ((i < 0) || (i >= MAX_TERM_DATA)) break;
2793
2794 if (!win_data[i].visible)
2795 {
2796 win_data[i].visible = TRUE;
2797 ShowWindow(win_data[i].w, SW_SHOW);
2798 term_data_redraw(&win_data[i]);
2799 }
2800 else
2801 {
2802 win_data[i].visible = FALSE;
2803 ShowWindow(win_data[i].w, SW_HIDE);
2804 }
2805
2806 break;
2807 }
2808
2809 /* Hack -- unused */
2810 case IDM_OPTIONS_UNUSED:
2811 {
2812 /* XXX XXX XXX */
2813 break;
2814 }
2815 /* Currently no graphics options available. -GP */
2816 #ifdef USE_GRAPHICS
2817 case IDM_GRAPHICS_OFF:
2818 {
2819 set_graphics_next(0);
2820 break;
2821 }
2822 case IDM_GRAPHICS_TILESET_1:
2823 case IDM_GRAPHICS_TILESET_2:
2824 case IDM_GRAPHICS_TILESET_3:
2825 case IDM_GRAPHICS_TILESET_4:
2826 case IDM_GRAPHICS_TILESET_5:
2827 case IDM_GRAPHICS_TILESET_6:
2828 case IDM_GRAPHICS_TILESET_7:
2829 case IDM_GRAPHICS_TILESET_8:
2830 {
2831 set_graphics_next(wCmd - IDM_GRAPHICS_TILESET_1 + 1);
2832 break;
2833 /* no support -GP */
2834 /* React to changes */
2835 //Term_xtra_win_react();
2836
2837 /* Hack -- Force redraw */
2838 //Term_key_push(KTRL('R'));
2839 }
2840 case IDM_GRAPHICS_BIG_TILE:
2841 {
2842 static int old_font_wid, old_font_hgt;
2843 /*
2844 if (!big_tile)
2845 {
2846 old_font_wid = win_data[0].font_wid;
2847 old_font_hgt = win_data[0].font_hgt;
2848 win_data[0].font_wid = infGraph.CellHeight;
2849 win_data[0].font_hgt = infGraph.CellHeight;
2850 } else {
2851 win_data[0].font_wid = old_font_wid;
2852 win_data[0].font_hgt = old_font_hgt;
2853 }
2854 */
2855 x_offset = 20;
2856 big_tile = !big_tile;
2857
2858 /* Hack -- Force redraw */
2859 Term_key_push(KTRL('R'));
2860 break;
2861 }
2862 #endif
2863 case IDM_OPTIONS_SOUND:
2864 {
2865 use_sound = !use_sound;
2866 Term_xtra_win_react();
2867 break;
2868 }
2869
2870 case IDM_OPTIONS_MOUSE:
2871 {
2872 use_mouse = !use_mouse;
2873 break;
2874 }
2875
2876 case IDM_HELP_GENERAL:
2877 {
2878 char buf[1024];
2879 char tmp[1024];
2880 path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "angband.hlp");
2881 sprintf(buf, "winhelp.exe %s", tmp);
2882 WinExec(buf, SW_NORMAL);
2883 break;
2884 }
2885
2886 case IDM_HELP_SPOILERS:
2887 {
2888 char buf[1024];
2889 char tmp[1024];
2890 path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "spoilers.hlp");
2891 sprintf(buf, "winhelp.exe %s", tmp);
2892 WinExec(buf, SW_NORMAL);
2893 break;
2894 }
2895 case IDM_HELP_ABOUT:
2896 {
2897 /*x_offset += 1;
2898 Term_redraw();*/
2899
2900 DialogBox(hInstance, "ABOUT" ,win_data[0].w, dDialogProc );
2901
2902 break;
2903 }
2904
2905 }
2906 #endif /* MNU_SUPPORT */
2907 }
2908
2909 #ifdef BEN_HACK
2910 LRESULT FAR PASCAL _export AngbandWndProc(HWND hWnd, UINT uMsg,
2911 WPARAM wParam, LPARAM lParam);
2912 #endif
2913
AngbandWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)2914 LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
2915 WPARAM wParam, LPARAM lParam)
2916 {
2917 PAINTSTRUCT ps;
2918 HDC hdc;
2919 term_data *td;
2920 MINMAXINFO FAR *lpmmi;
2921 RECT rc;
2922 int i;
2923
2924
2925 /* Acquire proper "term_data" info */
2926 td = (term_data *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
2927
2928 /* Handle message */
2929 switch (uMsg)
2930 {
2931 /* XXX XXX XXX */
2932 case WM_NCCREATE:
2933 {
2934 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(td_ptr));
2935 break;
2936 }
2937
2938 /* XXX XXX XXX */
2939 case WM_CREATE:
2940 {
2941 return 0;
2942 }
2943
2944 case WM_GETMINMAXINFO:
2945 {
2946 lpmmi = (MINMAXINFO FAR *)lParam;
2947
2948 if (!td) return 1; /* this message was sent before WM_NCCREATE */
2949
2950 /* Minimum window size is 8x2 */
2951 rc.left = rc.top = 0;
2952 rc.right = rc.left + 8 * td->font_wid + td->size_ow1 + td->size_ow2;
2953 rc.bottom = rc.top + 2 * td->font_hgt + td->size_oh1 + td->size_oh2 + 1;
2954
2955 /* Adjust */
2956 AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
2957
2958 /* Save minimum size */
2959 lpmmi->ptMinTrackSize.x = rc.right - rc.left;
2960 lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;
2961
2962 /* Maximum window size */
2963 rc.left = rc.top = 0;
2964 rc.right = rc.left + (MAX_WID+SCREEN_CLIP_X) * td->font_wid + td->size_ow1 + td->size_ow2;
2965 rc.bottom = rc.top + (MAX_HGT+SCREEN_CLIP_Y) * td->font_hgt + td->size_oh1 + td->size_oh2 + 1;
2966
2967 /* Paranoia */
2968 rc.right += (td->font_wid - 1);
2969 rc.bottom += (td->font_hgt - 1);
2970
2971 /* Adjust */
2972 AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
2973
2974 /* Save maximum size */
2975 lpmmi->ptMaxSize.x = rc.right - rc.left;
2976 lpmmi->ptMaxSize.y = rc.bottom - rc.top;
2977
2978 /* Save maximum size */
2979 lpmmi->ptMaxTrackSize.x = rc.right - rc.left;
2980 lpmmi->ptMaxTrackSize.y = rc.bottom - rc.top;
2981
2982 return 0;
2983 }
2984
2985 case WM_PAINT:
2986 {
2987 BeginPaint(hWnd, &ps);
2988 if (td) term_data_redraw(td);
2989 EndPaint(hWnd, &ps);
2990 ValidateRect(hWnd, NULL); /* why needed ?? */
2991 return 0;
2992 }
2993
2994 case WM_SYSKEYDOWN:
2995 case WM_KEYDOWN:
2996 {
2997 BYTE KeyState = 0x00;
2998 bool enhanced = FALSE;
2999 bool mc = FALSE;
3000 bool ms = FALSE;
3001 bool ma = FALSE;
3002
3003 /* Extract the modifiers */
3004 if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
3005 if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE;
3006 if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE;
3007
3008 /* Check for non-normal keys */
3009 if ((wParam >= VK_PRIOR) && (wParam <= VK_DOWN)) enhanced = TRUE;
3010 if ((wParam >= VK_F1) && (wParam <= VK_F12)) enhanced = TRUE;
3011 if ((wParam == VK_INSERT) || (wParam == VK_DELETE)) enhanced = TRUE;
3012
3013 /* XXX XXX XXX */
3014 if (enhanced)
3015 {
3016 /* Begin the macro trigger */
3017 Term_keypress(31);
3018
3019 /* Send the modifiers */
3020 if (mc) Term_keypress('C');
3021 if (ms) Term_keypress('S');
3022 if (ma) Term_keypress('A');
3023
3024 /* Extract "scan code" from bits 16..23 of lParam */
3025 i = LOBYTE(HIWORD(lParam));
3026
3027 /* Introduce the scan code */
3028 Term_keypress('x');
3029
3030 /* Encode the hexidecimal scan code */
3031 Term_keypress(hexsym[i/16]);
3032 Term_keypress(hexsym[i%16]);
3033
3034 /* End the macro trigger */
3035 Term_keypress(13);
3036
3037 return 0;
3038 }
3039
3040 break;
3041 }
3042
3043 case WM_CHAR:
3044 {
3045 Term_keypress(wParam);
3046 return 0;
3047 }
3048
3049 case WM_LBUTTONDOWN:
3050 case WM_MBUTTONDOWN:
3051 case WM_RBUTTONDOWN:
3052 #if defined(WM_XBUTTONDOWN)
3053 case WM_XBUTTONDOWN:
3054 #endif
3055 {
3056 int x = LOWORD(lParam);
3057 int y = HIWORD(lParam);
3058 int button = 1;
3059
3060 if (!td) return 1; /* this message was sent before WM_NCCREATE */
3061 if (!td->w) return 1; /* it was sent from inside CreateWindowEx */
3062 if (!Term) return 1; /* no active terminal yet */
3063
3064 x = x / td->font_wid;
3065 y = y / td->font_hgt;
3066
3067 /* Which button */
3068 if (uMsg == WM_LBUTTONDOWN) button = 1;
3069 if (uMsg == WM_MBUTTONDOWN) button = 2;
3070 if (uMsg == WM_RBUTTONDOWN) button = 3;
3071 #if defined(WM_XBUTTONDOWN)
3072 if (uMsg == WM_XBUTTONDOWN) button = 3 + HIWORD(wParam);
3073 #endif
3074
3075 /* Extract the modifiers */
3076 if (GetKeyState(VK_CONTROL) & 0x8000) button |= 16;
3077 if (GetKeyState(VK_SHIFT) & 0x8000) button |= 32;
3078 if (GetKeyState(VK_MENU) & 0x8000) button |= 64;
3079
3080 if (!use_mouse) return 0; /* No in-game mouse */
3081
3082 Term_mousepress(x, y, button);
3083 return 0;
3084 }
3085
3086 case WM_MOUSEMOVE:
3087 {
3088 int x = LOWORD(lParam);
3089 int y = HIWORD(lParam);
3090
3091 if (!td) return 1; /* this message was sent before WM_NCCREATE */
3092 if (!td->w) return 1; /* it was sent from inside CreateWindowEx */
3093 if (!Term) return 1; /* no active terminal yet */
3094
3095 x = x / td->font_wid;
3096 y = y / td->font_hgt;
3097
3098 Term_mousepress(x, y, 0);
3099 return 0;
3100 }
3101
3102 case WM_INITMENU:
3103 {
3104 setup_menus();
3105 return 0;
3106 }
3107
3108 case WM_CLOSE:
3109 case WM_QUIT:
3110 {
3111 quit(NULL);
3112 return 0;
3113 }
3114
3115 case WM_COMMAND:
3116 {
3117 process_menus(LOWORD(wParam));
3118 return 0;
3119 }
3120 /*
3121 case WM_ENTERSIZEMOVE:
3122 {
3123 return 0;
3124 }
3125 */
3126 case WM_EXITSIZEMOVE:
3127 {
3128 term *old = Term;
3129
3130 if (!td) return 1; /* this message was sent before WM_NCCREATE */
3131 if (!td->w) return 1; /* it was sent from inside CreateWindowEx */
3132 if (!conn_state) return 1;
3133
3134 if (td->t.wid != td->cols || td->t.hgt != td->rows)
3135 {
3136 Term_resize(td->cols, td->rows);
3137 net_term_manage(window_flag, window_flag, FALSE);
3138 }
3139
3140 return 0;
3141 }
3142
3143 case WM_SIZE:
3144 {
3145 if (!td) return 1; /* this message was sent before WM_NCCREATE */
3146 if (!td->w) return 1; /* it was sent from inside CreateWindowEx */
3147 if (td->size_hack) return 1; /* was sent from WM_SIZE */
3148
3149 switch (wParam)
3150 {
3151 case SIZE_MINIMIZED:
3152 {
3153 for (i = 1; i < MAX_TERM_DATA; i++)
3154 {
3155 if (win_data[i].visible) ShowWindow(win_data[i].w, SW_HIDE);
3156 }
3157 return 0;
3158 }
3159
3160 case SIZE_MAXIMIZED:
3161 {
3162 /* fall through XXX XXX XXX */
3163 }
3164
3165 case SIZE_RESTORED:
3166 {
3167 term *old = Term;
3168
3169 td->size_hack = TRUE;
3170
3171 td->cols = (LOWORD(lParam) - td->size_ow1 - td->size_ow2) / td->font_wid;
3172 td->rows = (HIWORD(lParam) - td->size_oh1 - td->size_oh2) / td->font_hgt;
3173
3174 term_getsize(td);
3175
3176 MoveWindow(hWnd, td->pos_x, td->pos_y, td->size_wid, td->size_hgt, TRUE);
3177
3178 td->size_hack = FALSE;
3179
3180 /* Windows */
3181 for (i = 1; i < MAX_TERM_DATA; i++)
3182 {
3183 if (win_data[i].visible) ShowWindow(win_data[i].w, SW_SHOWNOACTIVATE);
3184 }
3185
3186 /* Changed size (before loggin in) */
3187 Term_resize(td->cols, td->rows);
3188 if (!conn_state)
3189 {
3190 net_term_manage(window_flag, window_flag, FALSE);
3191 }
3192
3193 return 0;
3194 }
3195 }
3196 break;
3197 }
3198
3199 case WM_PALETTECHANGED:
3200 {
3201 /* ignore if palette change caused by itself */
3202 if ((HWND)wParam == hWnd) return FALSE;
3203 /* otherwise, fall through!!! */
3204 }
3205
3206 case WM_QUERYNEWPALETTE:
3207 {
3208 if (!paletted) return FALSE;
3209 hdc = GetDC(hWnd);
3210 SelectPalette(hdc, hPal, FALSE);
3211 i = RealizePalette(hdc);
3212 /* if any palette entries changed, repaint the window. */
3213 if (i) InvalidateRect(hWnd, NULL, TRUE);
3214 ReleaseDC(hWnd, hdc);
3215 return FALSE;
3216 }
3217
3218 case WM_ACTIVATE:
3219 {
3220 if (wParam && !HIWORD(lParam))
3221 {
3222 for (i = 1; i < MAX_TERM_DATA; i++)
3223 {
3224 SetWindowPos(win_data[i].w, hWnd, 0, 0, 0, 0,
3225 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
3226 }
3227 SetFocus(hWnd);
3228 return 0;
3229 }
3230 break;
3231 }
3232 }
3233
3234
3235 /* Oops */
3236 return DefWindowProc(hWnd, uMsg, wParam, lParam);
3237 }
3238
3239
3240 #ifdef BEN_HACK
3241 LRESULT FAR PASCAL _export AngbandListProc(HWND hWnd, UINT uMsg,
3242 WPARAM wParam, LPARAM lParam);
3243 #endif
3244
AngbandListProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)3245 LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
3246 WPARAM wParam, LPARAM lParam)
3247 {
3248 term_data *td;
3249 MINMAXINFO FAR *lpmmi;
3250 RECT rc;
3251 PAINTSTRUCT ps;
3252 HDC hdc;
3253 int i,j;
3254 char pmsg[60];
3255
3256
3257 /* Acquire proper "term_data" info */
3258 td = (term_data *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
3259
3260 /* Process message */
3261 switch (uMsg)
3262 {
3263 /* XXX XXX XXX */
3264 case WM_NCCREATE:
3265 {
3266 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(td_ptr));
3267 break;
3268 }
3269
3270 /* XXX XXX XXX */
3271 case WM_CREATE:
3272 {
3273 return 0;
3274 }
3275
3276 case 0x133: /* WM_CTLCOLOREDIT */
3277 {
3278 SetTextColor((HDC)wParam,0x00ffffff);
3279 SetBkColor((HDC)wParam, 0);
3280 return (int)hbrBlack;
3281 }
3282
3283 /* GRK, wasn't trapping this so vis menus got messed up */
3284 /* We fake a click on the visibilty menu when the close icon is clicked */
3285
3286 case WM_CLOSE:
3287 /* Which term is closing ? */
3288 j=-1;
3289 for(i=0; i<MAX_TERM_DATA;i++)
3290 if(&win_data[i] == td) j = i;
3291 /* Click its menu entry */
3292 if(j != -1) process_menus(211+j);
3293 return 0;
3294
3295 case WM_GETMINMAXINFO:
3296 {
3297 if (!td) return 1; /* this message was sent before WM_NCCREATE */
3298
3299 lpmmi = (MINMAXINFO FAR *)lParam;
3300
3301 /* Minimum size */
3302 rc.left = rc.top = 0;
3303 rc.right = rc.left + 8 * td->font_wid + td->size_ow1 + td->size_ow2;
3304 rc.bottom = rc.top + 2 * td->font_hgt + td->size_oh1 + td->size_oh2;
3305
3306 /* Adjust */
3307 AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
3308
3309 /* Save the minimum size */
3310 lpmmi->ptMinTrackSize.x = rc.right - rc.left;
3311 lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;
3312
3313 /* Maximum window size */
3314 rc.left = rc.top = 0;
3315 rc.right = rc.left + 80 * td->font_wid + td->size_ow1 + td->size_ow2;
3316 rc.bottom = rc.top + 24 * td->font_hgt + td->size_oh1 + td->size_oh2;
3317
3318 /* Paranoia */
3319 rc.right += (td->font_wid - 1);
3320 rc.bottom += (td->font_hgt - 1);
3321
3322 /* Adjust */
3323 AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);
3324
3325 /* Save maximum size */
3326 lpmmi->ptMaxSize.x = rc.right - rc.left;
3327 lpmmi->ptMaxSize.y = rc.bottom - rc.top;
3328
3329 /* Save the maximum size */
3330 lpmmi->ptMaxTrackSize.x = rc.right - rc.left;
3331 lpmmi->ptMaxTrackSize.y = rc.bottom - rc.top;
3332
3333 return 0;
3334 }
3335 case WM_EXITSIZEMOVE:
3336 {
3337 /* Force redraw to remove artifacts */
3338 InvalidateRect(hWnd,NULL,TRUE);
3339 return 0;
3340 }
3341 case WM_SIZE:
3342 {
3343 term *old = Term;
3344
3345 if (!td) return 1; /* this message was sent before WM_NCCREATE */
3346 if (!td->w) return 1; /* it was sent from inside CreateWindowEx */
3347 if (td->size_hack) return 1; /* was sent from inside WM_SIZE */
3348
3349 td->size_hack = TRUE;
3350
3351 td->cols = (LOWORD(lParam) - td->size_ow1 - td->size_ow2) / td->font_wid;
3352 td->rows = (HIWORD(lParam) - td->size_oh1 - td->size_oh2) / td->font_hgt;
3353
3354 term_getsize(td);
3355
3356 term_data_resize(td, FALSE);
3357 /* Gross hack -- find needed terminal number */
3358 for (i = 1; i < ANGBAND_TERM_MAX; i++) {
3359 if ((ang_term[i]) == &(td->t)) {
3360 p_ptr->window |= window_flag[i];
3361 }
3362 }
3363 window_stuff();
3364
3365 MoveWindow(hWnd, td->pos_x, td->pos_y, td->size_wid, td->size_hgt, TRUE);
3366 if(td == &win_data[4]) stretch_chat_ctrl();
3367
3368 td->size_hack = FALSE;
3369
3370 return 0;
3371 }
3372
3373 case WM_PAINT:
3374 {
3375 BeginPaint(hWnd, &ps);
3376 if (td) term_data_redraw(td);
3377 EndPaint(hWnd, &ps);
3378 return 0;
3379 }
3380
3381 case WM_SYSKEYDOWN:
3382 case WM_KEYDOWN:
3383 {
3384 BYTE KeyState = 0x00;
3385 bool enhanced = FALSE;
3386 bool mc = FALSE;
3387 bool ms = FALSE;
3388 bool ma = FALSE;
3389
3390 /* Which term getting the keypress ? */
3391 j=-1;
3392 for(i=0; i<MAX_TERM_DATA;i++)
3393 if(&win_data[i] == td) j = i;
3394 /* If this is term7 we are sending a player message */
3395 if(j == 7){
3396 /* Is this RETURN ? */
3397 if( wParam == 13){
3398 /* Get the controls text and send it */
3399 GetWindowText(editmsg, pmsg, 59);
3400 send_msg(pmsg);
3401 }
3402 /* If not return, ignore key */
3403 return 0;
3404 }
3405
3406 /* Extract the modifiers */
3407 if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
3408 if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE;
3409 if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE;
3410
3411 /* Check for non-normal keys */
3412 if ((wParam >= VK_PRIOR) && (wParam <= VK_DOWN)) enhanced = TRUE;
3413 if ((wParam >= VK_F1) && (wParam <= VK_F12)) enhanced = TRUE;
3414 if ((wParam == VK_INSERT) || (wParam == VK_DELETE)) enhanced = TRUE;
3415
3416 /* XXX XXX XXX */
3417 if (enhanced)
3418 {
3419 /* Begin the macro trigger */
3420 Term_keypress(31);
3421
3422 /* Send the modifiers */
3423 if (mc) Term_keypress('C');
3424 if (ms) Term_keypress('S');
3425 if (ma) Term_keypress('A');
3426
3427 /* Extract "scan code" from bits 16..23 of lParam */
3428 i = LOBYTE(HIWORD(lParam));
3429
3430 /* Introduce the scan code */
3431 Term_keypress('x');
3432
3433 /* Encode the hexidecimal scan code */
3434 Term_keypress(hexsym[i/16]);
3435 Term_keypress(hexsym[i%16]);
3436
3437 /* End the macro trigger */
3438 Term_keypress(13);
3439
3440 return 0;
3441 }
3442
3443 break;
3444 }
3445
3446 case WM_CHAR:
3447 {
3448 Term_keypress(wParam);
3449 return 0;
3450 }
3451
3452 case WM_PALETTECHANGED:
3453 {
3454 /* ignore if palette change caused by itself */
3455 if ((HWND)wParam == hWnd) return FALSE;
3456 /* otherwise, fall through!!! */
3457 }
3458
3459 case WM_QUERYNEWPALETTE:
3460 {
3461 if (!paletted) return 0;
3462 hdc = GetDC(hWnd);
3463 SelectPalette(hdc, hPal, FALSE);
3464 i = RealizePalette(hdc);
3465 /* if any palette entries changed, repaint the window. */
3466 if (i) InvalidateRect(hWnd, NULL, TRUE);
3467 ReleaseDC(hWnd, hdc);
3468 return 0;
3469 }
3470
3471 case WM_NCLBUTTONDOWN:
3472 {
3473 if (wParam == HTSYSMENU)
3474 {
3475 /* Hide sub-windows */
3476 if (td != &win_data[0])
3477 {
3478 if (td->visible)
3479 {
3480 td->visible = FALSE;
3481 ShowWindow(td->w, SW_HIDE);
3482 }
3483 }
3484 return 0;
3485 }
3486 break;
3487 }
3488
3489 }
3490
3491 return DefWindowProc(hWnd, uMsg, wParam, lParam);
3492 }
3493
3494
3495 #ifdef ALLOW_SCRSAVER
3496
3497 #define MOUSE_SENS 40
3498
AngbandSaverProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)3499 LRESULT FAR PASCAL _export AngbandSaverProc(HWND hWnd, UINT uMsg,
3500 WPARAM wParam, LPARAM lParam)
3501 {
3502 static int iMouse = 0;
3503 static WORD xMouse = 0;
3504 static WORD yMouse = 0;
3505
3506 int dx, dy;
3507
3508 term_data *td;
3509
3510
3511 /* Acquire proper "term_data" info */
3512 td = (term_data *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
3513
3514 /* Process */
3515 switch (uMsg)
3516 {
3517 /* XXX XXX XXX */
3518 case WM_NCCREATE:
3519 {
3520 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(td_ptr));
3521 break;
3522 }
3523
3524 case WM_SETCURSOR:
3525 {
3526 SetCursor(NULL);
3527 return 0;
3528 }
3529
3530 #if 0
3531 case WM_ACTIVATE:
3532 {
3533 if (LOWORD(wParam) == WA_INACTIVE) break;
3534
3535 /* else fall through */
3536 }
3537 #endif
3538
3539 case WM_LBUTTONDOWN:
3540 case WM_MBUTTONDOWN:
3541 case WM_RBUTTONDOWN:
3542 case WM_KEYDOWN:
3543 {
3544 SendMessage(hWnd, WM_CLOSE, 0, 0);
3545 return 0;
3546 }
3547
3548 case WM_MOUSEMOVE:
3549 {
3550 if (iMouse)
3551 {
3552 dx = LOWORD(lParam) - xMouse;
3553 dy = HIWORD(lParam) - yMouse;
3554
3555 if (dx < 0) dx = -dx;
3556 if (dy < 0) dy = -dy;
3557
3558 if ((dx > MOUSE_SENS) || (dy > MOUSE_SENS))
3559 {
3560 SendMessage(hWnd, WM_CLOSE, 0, 0);
3561 }
3562 }
3563
3564 iMouse = 1;
3565 xMouse = LOWORD(lParam);
3566 yMouse = HIWORD(lParam);
3567 return 0;
3568 }
3569
3570 case WM_CLOSE:
3571 {
3572 DestroyWindow(hWnd);
3573 return 0;
3574 }
3575 }
3576
3577 /* Oops */
3578 return DefWindowProc(hWnd, uMsg, wParam, lParam);
3579 }
3580
3581 #endif
3582
3583
3584
3585
3586
3587 /*** Temporary Hooks ***/
3588
3589
3590 /*
3591 * Error message -- See "z-util.c"
3592 */
hack_plog(cptr str)3593 static void hack_plog(cptr str)
3594 {
3595 /* Give a warning */
3596 /* if (str) c_msg_print(str); */
3597 if (str) MessageBox(NULL, str, "Warning", MB_OK);
3598 }
3599
3600
3601 /*
3602 * Quit with error message -- See "z-util.c"
3603 */
hack_quit(cptr str)3604 static void hack_quit(cptr str)
3605 {
3606 int i;
3607
3608 /* Force saving of preferences on any quit [grk] */
3609 save_prefs();
3610
3611 /* Give a warning */
3612 if (str && str[0]) MessageBox(NULL, str, "Error", MB_OK | MB_ICONSTOP);
3613
3614 /* Sub-Windows */
3615 for (i = MAX_TERM_DATA - 1; i >= 1; i--)
3616 {
3617 term_force_font(&win_data[i], NULL);
3618 if (win_data[i].font_want) string_free(win_data[i].font_want);
3619 if (win_data[i].graf_want) string_free(win_data[i].graf_want);
3620 if (win_data[i].w) DestroyWindow(win_data[i].w);
3621 win_data[i].w = 0;
3622 }
3623
3624 #ifdef USE_GRAPHICS
3625 /* Free the bitmap stuff */
3626 FreeDIB(&infGraph);
3627 FreeDIB(&infMask);
3628 #endif
3629 /* Forget grafmodes */
3630 close_graphics_modes();
3631
3632
3633 term_force_font(&win_data[0], NULL);
3634 if (win_data[0].font_want) string_free(win_data[0].font_want);
3635 if (win_data[0].graf_want) string_free(win_data[0].graf_want);
3636 if (win_data[0].w) DestroyWindow(win_data[0].w);
3637 win_data[0].w = 0;
3638
3639 /* Unregister the classes */
3640 UnregisterClass(AppName, hInstance);
3641
3642 /* Destroy the icon */
3643 if (hIcon) DestroyIcon(hIcon);
3644
3645 /* Cleanup WinSock */
3646 cleanup_network_client();
3647
3648 /* Exit */
3649 exit (0);
3650 }
3651
3652
3653 /*
3654 * Fatal error (see "z-util.c")
3655 */
hack_core(cptr str)3656 static void hack_core(cptr str)
3657 {
3658 /* Give a warning */
3659 if (str) MessageBox(NULL, str, "Error", MB_OK | MB_ICONSTOP);
3660
3661 /* Quit */
3662 quit (NULL);
3663 }
3664
3665
3666 /*** Various hooks ***/
3667
3668
3669 /*
3670 * Error message -- See "z-util.c"
3671 */
hook_plog(cptr str)3672 static void hook_plog(cptr str)
3673 {
3674 /* Warning */
3675 if (str) MessageBox(win_data[0].w, str, "Warning", MB_OK);
3676 }
3677
3678
3679 /*
3680 * Quit with error message -- See "z-util.c"
3681 *
3682 * A lot of this function should be handled by actually calling
3683 * the "term_nuke()" function hook for each window. XXX XXX XXX
3684 */
hook_quit(cptr str)3685 static void hook_quit(cptr str)
3686 {
3687 int i;
3688
3689 #ifdef USE_SOUND
3690 int j;
3691 #endif /* USE_SOUND */
3692
3693 /* Give a warning */
3694 if (str) MessageBox(win_data[0].w, str, "Error", MB_OK | MB_ICONSTOP);
3695
3696
3697 /* Save the preferences */
3698 save_prefs();
3699
3700 /* Sub-Windows */
3701 for (i = MAX_TERM_DATA - 1; i >= 1; i--)
3702 {
3703 term_force_font(&win_data[i], NULL);
3704 if (win_data[i].font_want) string_free(win_data[i].font_want);
3705 if (win_data[i].graf_want) string_free(win_data[i].graf_want);
3706 if (win_data[i].w) DestroyWindow(win_data[i].w);
3707 win_data[i].w = 0;
3708 }
3709
3710 #ifdef USE_GRAPHICS
3711 /* Free the bitmap stuff */
3712 FreeDIB(&infGraph);
3713 FreeDIB(&infMask);
3714 #endif
3715
3716 #ifdef USE_SOUND
3717 /* Free the sound names */
3718 for (i = 0; i < MSG_MAX; i++)
3719 {
3720 for (j = 0; j < SAMPLE_MAX; j++)
3721 {
3722 if (!sound_file[i][j]) break;
3723
3724 string_free(sound_file[i][j]);
3725 }
3726 }
3727 #endif /* USE_SOUND */
3728
3729 term_force_font(&win_data[0], NULL);
3730 if (win_data[0].font_want) string_free(win_data[0].font_want);
3731 if (win_data[0].graf_want) string_free(win_data[0].graf_want);
3732 if (win_data[0].w) DestroyWindow(win_data[0].w);
3733 win_data[0].w = 0;
3734
3735
3736 /*** Free some other stuff ***/
3737
3738 DeleteObject(hbrYellow);
3739
3740 if (hPal) DeleteObject(hPal);
3741
3742 UnregisterClass(AppName, hInstance);
3743
3744 if (hIcon) DestroyIcon(hIcon);
3745
3746 //network_done();
3747
3748 /* Free strings */
3749
3750 exit(0);
3751 }
3752
3753
3754
3755 /*** Initialize ***/
3756
3757
3758 /*
3759 * Init some stuff
3760 */
init_stuff_win(void)3761 void static init_stuff_win(void)
3762 {
3763 int i;
3764
3765 char path[1024];
3766
3767 #ifdef USE_GRAPHICS
3768 graphics_mode *gm;
3769 #endif
3770
3771 /* XXX XXX XXX */
3772 strcpy(path, conf_get_string("Windows32", "LibPath", ".\\lib"));
3773
3774 /* Analyze the path */
3775 i = strlen(path);
3776
3777 /* Require a path */
3778 if (!i) quit("LibPath shouldn't be empty in ANGBAND.INI");
3779
3780 /* Nuke terminal backslash */
3781 if (i && (path[i-1] != '\\'))
3782 {
3783 path[i++] = '\\';
3784 path[i] = '\0';
3785 }
3786
3787 /* Validate the path */
3788 validate_dir(path);
3789
3790
3791 /* Init the file paths */
3792
3793 init_file_paths(path);
3794
3795 /* Hack -- Validate the paths */
3796
3797 /* validate_dir(ANGBAND_DIR_APEX); *//*on server */
3798 /* validate_dir(ANGBAND_DIR_EDIT); */
3799 /* validate_dir(ANGBAND_DIR_FILE); */
3800 /* validate_dir(ANGBAND_DIR_HELP); */
3801 validate_dir(ANGBAND_DIR_BONE);
3802 validate_dir(ANGBAND_DIR_PREF);
3803 validate_dir(ANGBAND_DIR_USER);
3804 validate_dir(ANGBAND_DIR_XTRA); /*sounds & graphics */
3805
3806
3807 // Build the "font" path
3808 path_build(path, 1024, ANGBAND_DIR_XTRA, "font");
3809
3810 // Allocate the path
3811 ANGBAND_DIR_XTRA_FONT = string_make(path);
3812
3813 // Validate the "font" directory
3814 validate_dir(ANGBAND_DIR_XTRA_FONT);
3815
3816 // Build the filename
3817 path_build(path, 1024, ANGBAND_DIR_XTRA_FONT, "8X13.FON");
3818
3819 // Hack -- Validate the basic font
3820 validate_file(path);
3821
3822
3823 #ifdef USE_GRAPHICS
3824
3825 /* Validate the "graf" directory */
3826 validate_dir(ANGBAND_DIR_XTRA_GRAF);
3827
3828 /* Pick graphics mode */
3829 if ((gm = get_graphics_mode((byte)use_graphics)))
3830 {
3831 /* Build the filename */
3832 path_build(path, 1024, ANGBAND_DIR_XTRA_GRAF, gm->file);
3833
3834 /* Hack -- Validate the basic graf */
3835 validate_file(path);
3836 }
3837 #endif
3838
3839
3840 #ifdef USE_SOUND
3841
3842 /* Validate the "sound" directory */
3843 validate_dir(ANGBAND_DIR_XTRA_SOUND);
3844
3845 #endif
3846
3847 }
3848
3849
3850
WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)3851 int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
3852 LPSTR lpCmdLine, int nCmdShow)
3853 {
3854 #ifdef USE_GRAPHICS
3855 int i;
3856 #endif
3857
3858 WNDCLASS wc;
3859 HDC hdc;
3860 MSG msg;
3861 //WSADATA wsadata;
3862
3863 hInstance = hInst; /* save in a global var */
3864
3865 if (hPrevInst == NULL)
3866 {
3867 wc.style = CS_CLASSDC;
3868 wc.lpfnWndProc = AngbandWndProc;
3869 wc.cbClsExtra = 0;
3870 wc.cbWndExtra = 4; /* one long pointer to term_data */
3871 wc.hInstance = hInst;
3872 wc.hIcon = hIcon = LoadIcon(hInst, AppName);
3873 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
3874 wc.hbrBackground = GetStockObject(BLACK_BRUSH);
3875 wc.lpszMenuName = AppName;
3876 wc.lpszClassName = AppName;
3877
3878 if (!RegisterClass(&wc)) exit(1);
3879
3880 wc.lpfnWndProc = AngbandListProc;
3881 wc.lpszMenuName = NULL;
3882 wc.lpszClassName = AngList;
3883
3884 if (!RegisterClass(&wc)) exit(2);
3885
3886 #ifdef ALLOW_SCRSAVER
3887
3888 wc.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_DBLCLKS;
3889 wc.lpfnWndProc = AngbandSaverProc;
3890 wc.hCursor = NULL;
3891 wc.lpszMenuName = NULL;
3892 wc.lpszClassName = "WindowsScreenSaverClass";
3893
3894 if (!RegisterClass(&wc)) exit(3);
3895
3896 #endif
3897
3898 }
3899
3900 /* Set hooks */
3901 quit_aux = hack_quit;
3902 core_aux = hack_core;
3903 plog_aux = hack_plog;
3904
3905 /* Global client config */
3906 conf_init(hInstance);
3907
3908 /* Prepare the filepaths */
3909 init_stuff_win();
3910
3911 /* Initialize WinSock */
3912 // WSAStartup(MAKEWORD(1, 1), &wsadata);
3913
3914 /* Determine if display is 16/256/true color */
3915 hdc = GetDC(NULL);
3916 colors16 = (GetDeviceCaps(hdc, BITSPIXEL) == 4);
3917 paletted = ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? TRUE : FALSE);
3918 ReleaseDC(NULL, hdc);
3919 #ifdef USE_GRAPHICS
3920 /* Initialize "color_table" */
3921 for (i = 0; i < 16; i++)
3922 {
3923 /* Save the "complex" codes */
3924 color_table[i][1] = GetRValue(win_clr[i]);
3925 color_table[i][2] = GetGValue(win_clr[i]);
3926 color_table[i][3] = GetBValue(win_clr[i]);
3927
3928 /* Save the "simple" code */
3929 color_table[i][0] = win_pal[i];
3930 }
3931 #endif
3932
3933 /* load the possible graphics modes */
3934 if (!init_graphics_modes("graphics.txt")) {
3935 plog("Graphics list load failed");
3936 }
3937
3938 /* Prepare the windows */
3939 init_windows();
3940
3941 /* Set the system suffix */
3942 ANGBAND_SYS = "win";
3943
3944 /* We are now initialized */
3945 initialized = TRUE;
3946
3947 /* Do network initialization, etc. */
3948 client_init();
3949
3950 /* Process messages forever */
3951 while (GetMessage(&msg, NULL, 0, 0))
3952 {
3953 TranslateMessage(&msg);
3954 DispatchMessage(&msg);
3955 }
3956
3957 cleanup_network_client();
3958
3959 /* Paranoia */
3960 quit(NULL);
3961
3962 /* Paranoia */
3963 return (0);
3964 }
3965
3966 #endif /* _Windows */
3967