1 /* NetHack 3.6 wingem.c $NHDT-Date: 1450453304 2015/12/18 15:41:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.26 $ */
2 /* Copyright (c) Christian Bressler, 1999 */
3 /* NetHack may be freely redistributed. See license for details. */
12 #include "patchlevel.h"
18 static char nullstr[] = "", winpanicstr[] = "Bad window id %d";
19 static int curr_status_line;
21 static char *FDECL(copy_of, (const char *));
22 static void FDECL(bail, (const char *)); /* __attribute__((noreturn)) */
24 extern int mar_set_tile_mode(int);
25 extern void mar_set_font(int, const char *, int);
26 extern void mar_set_margin(int);
27 extern void mar_set_msg_visible(int);
28 extern void mar_set_status_align(int);
29 extern void mar_set_msg_align(int);
30 extern void mar_set_tilefile(char *);
31 extern void mar_set_tilex(int);
32 extern void mar_set_tiley(int);
33 extern short glyph2tile[MAX_GLYPH]; /* from tile.c */
34 extern void mar_display_nhwindow(winid); /* from wingem1.c */
36 void Gem_outrip(winid, int, time_t);
37 void Gem_preference_update(const char *);
38 /* Interface definition, for windows.c */
39 struct window_procs Gem_procs = {
41 WC_COLOR | WC_HILITE_PET | WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_INVERSE
42 | WC_SCROLL_MARGIN | WC_FONT_MESSAGE | WC_FONT_STATUS | WC_FONT_MENU
43 | WC_FONT_TEXT | WC_FONT_MAP | WC_FONTSIZ_MESSAGE | WC_FONTSIZ_STATUS
44 | WC_FONTSIZ_MENU | WC_FONTSIZ_TEXT | WC_FONTSIZ_MAP | WC_TILE_WIDTH
45 | WC_TILE_HEIGHT | WC_TILE_FILE | WC_VARY_MSGCOUNT | WC_ASCII_MAP,
47 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
48 Gem_init_nhwindows, Gem_player_selection, Gem_askname,
49 Gem_get_nh_event, Gem_exit_nhwindows, Gem_suspend_nhwindows,
50 Gem_resume_nhwindows, Gem_create_nhwindow, Gem_clear_nhwindow,
51 Gem_display_nhwindow, Gem_destroy_nhwindow, Gem_curs, Gem_putstr,
52 genl_putmixed, Gem_display_file, Gem_start_menu, Gem_add_menu,
53 Gem_end_menu, Gem_select_menu, genl_message_menu, Gem_update_inventory,
54 Gem_mark_synch, Gem_wait_synch,
59 Gem_update_positionbar,
61 Gem_print_glyph, Gem_raw_print, Gem_raw_print_bold, Gem_nhgetch,
62 Gem_nh_poskey, Gem_nhbell, Gem_doprev_message, Gem_yn_function,
63 Gem_getlin, Gem_get_ext_cmd, Gem_number_pad, Gem_delay_output,
64 #ifdef CHANGE_COLOR /* the Mac uses a palette device */
67 Gem_change_background, Gem_set_font_name,
72 /* other defs that really should go away (they're tty specific) */
73 Gem_start_screen, Gem_end_screen, Gem_outrip, Gem_preference_update,
74 genl_getmsghistory, genl_putmsghistory
76 genl_status_finish, genl_status_enablefield, genl_status_update,
82 Gem_change_background(dummy)
88 Gem_set_font_name(foo, bar)
95 /*************************** Proceduren *************************************/
101 return (u.mh ? u.mhmax / u.mh : -1);
102 return (u.uhp ? u.uhpmax / u.uhp : -1);
108 return (iflags.num_pad ? 1 : 0);
112 mar_get_msg_history()
114 return (iflags.msg_history);
118 mar_get_msg_visible()
120 return (iflags.wc_vary_msgcount);
122 /* clean up and quit */
128 Gem_exit_nhwindows(mesg);
129 nh_terminate(EXIT_SUCCESS);
134 #define DEF_CLIPAROUND_MARGIN -1
139 #define TILES_PER_LINE 20
140 #define NHFONT_DEFAULT_SIZE 10
141 #define NHFONT_SIZE_MIN 3
142 #define NHFONT_SIZE_MAX 20
146 Gem_init_nhwindows(argcp, argv)
150 argv = argv, argcp = argcp;
151 colors_changed = TRUE;
153 set_wc_option_mod_status(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS
154 | WC_TILE_WIDTH | WC_TILE_HEIGHT
157 set_wc_option_mod_status(
158 WC_HILITE_PET | WC_SCROLL_MARGIN | WC_FONT_MESSAGE | WC_FONT_MAP
159 | WC_FONT_STATUS | WC_FONT_MENU | WC_FONT_TEXT
160 | WC_FONTSIZ_MESSAGE | WC_FONTSIZ_MAP | WC_FONTSIZ_STATUS
161 | WC_FONTSIZ_MENU | WC_FONTSIZ_TEXT | WC_VARY_MSGCOUNT,
163 if (iflags.wc_align_message == 0)
164 iflags.wc_align_message = ALIGN_TOP;
165 if (iflags.wc_align_status == 0)
166 iflags.wc_align_status = ALIGN_BOTTOM;
167 if (iflags.wc_scroll_margin == 0)
168 iflags.wc_scroll_margin = DEF_CLIPAROUND_MARGIN;
169 if (iflags.wc_tile_width == 0)
170 iflags.wc_tile_width = TILE_X;
171 if (iflags.wc_tile_height == 0)
172 iflags.wc_tile_height = TILE_Y;
173 if (iflags.wc_tile_file && *iflags.wc_tile_file)
174 mar_set_tilefile(iflags.wc_tile_file);
175 if (iflags.wc_vary_msgcount == 0)
176 iflags.wc_vary_msgcount = 3;
178 !iflags.wc_ascii_map); /* MAR -- 17.Mar 2002 True is tiles */
179 mar_set_tilex(iflags.wc_tile_width);
180 mar_set_tiley(iflags.wc_tile_height);
181 mar_set_msg_align(iflags.wc_align_message - ALIGN_BOTTOM);
182 mar_set_status_align(iflags.wc_align_status - ALIGN_BOTTOM);
183 if (mar_gem_init() == 0) {
187 iflags.window_inited = TRUE;
189 CO = 80; /* MAR -- whatsoever */
192 add_menu_cmd_alias(' ', MENU_NEXT_PAGE);
193 mar_set_no_glyph(NO_GLYPH);
197 Gem_player_selection()
200 char pick4u = 'n', pbuf[QBUFSZ], lastch = 0, currch;
203 menu_item *selected = NULL;
205 /* avoid unnecessary prompts further down */
208 /* Should we randomly pick for the player? */
210 && (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE
211 || flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)) {
212 /* pick4u = yn_function("Shall I pick a character for you?
213 * [ynq]",ynqchars,'n');*/
214 pick4u = yn_function(build_plselection_prompt(
215 pbuf, QBUFSZ, flags.initrole, flags.initrace,
216 flags.initgend, flags.initalign),
219 give_up: /* Just quit */
221 free((genericptr_t) selected);
228 /* Select a role, if necessary */
229 if (flags.initrole < 0) {
230 /* Process the choice */
231 if (pick4u == 'y' || flags.initrole == ROLE_RANDOM
232 || flags.randomall) {
233 /* Pick a random role */
234 flags.initrole = pick_role(flags.initrace, flags.initgend,
235 flags.initalign, PICK_RANDOM);
236 if (flags.initrole < 0) {
237 mar_add_message("Incompatible role!");
238 mar_display_nhwindow(WIN_MESSAGE);
239 flags.initrole = randrole(FALSE);
242 /* Prompt for a role */
243 win = create_nhwindow(NHW_MENU);
245 any.a_void = 0; /* zero out all bits */
246 for (i = 0; roles[i].name.m; i++) {
247 if (ok_role(i, flags.initrace, flags.initgend,
249 any.a_int = i + 1; /* must be non-zero */
250 currch = lowc(roles[i].name.m[0]);
251 if (currch == lastch)
252 currch = highc(currch);
253 add_menu(win, roles[i].malenum, &any, currch, 0, ATR_NONE,
254 an(roles[i].name.m), MENU_UNSELECTED);
258 any.a_int = pick_role(flags.initrace, flags.initgend,
259 flags.initalign, PICK_RANDOM) + 1;
260 if (any.a_int == 0) /* must be non-zero */
261 any.a_int = randrole(FALSE) + 1;
262 add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
264 any.a_int = i + 1; /* must be non-zero */
265 add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
267 end_menu(win, "Pick a role");
268 n = select_menu(win, PICK_ONE, &selected);
269 destroy_nhwindow(win);
271 /* Process the choice */
272 if (n != 1 || selected[0].item.a_int == any.a_int)
273 goto give_up; /* Selected quit */
275 flags.initrole = selected[0].item.a_int - 1;
276 free((genericptr_t) selected), selected = 0;
280 /* Select a race, if necessary */
281 /* force compatibility with role, try for compatibility with
282 * pre-selected gender/alignment */
283 if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) {
284 /* pre-selected race not valid */
285 if (pick4u == 'y' || flags.initrace == ROLE_RANDOM
286 || flags.randomall) {
287 flags.initrace = pick_race(flags.initrole, flags.initgend,
288 flags.initalign, PICK_RANDOM);
289 if (flags.initrace < 0) {
290 mar_add_message("Incompatible race!");
291 mar_display_nhwindow(WIN_MESSAGE);
292 flags.initrace = randrace(flags.initrole);
294 } else { /* pick4u == 'n' */
295 /* Count the number of valid races */
296 n = 0; /* number valid */
297 k = 0; /* valid race */
298 for (i = 0; races[i].noun; i++) {
299 if (ok_race(flags.initrole, i, flags.initgend,
306 for (i = 0; races[i].noun; i++) {
307 if (validrace(flags.initrole, i)) {
313 /* Permit the user to pick, if there is more than one */
315 win = create_nhwindow(NHW_MENU);
317 any.a_void = 0; /* zero out all bits */
318 for (i = 0; races[i].noun; i++)
319 if (ok_race(flags.initrole, i, flags.initgend,
321 any.a_int = i + 1; /* must be non-zero */
322 add_menu(win, NO_GLYPH, &any, races[i].noun[0], 0,
323 ATR_NONE, races[i].noun, MENU_UNSELECTED);
325 any.a_int = pick_race(flags.initrole, flags.initgend,
326 flags.initalign, PICK_RANDOM) + 1;
327 if (any.a_int == 0) /* must be non-zero */
328 any.a_int = randrace(flags.initrole) + 1;
329 add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
331 any.a_int = i + 1; /* must be non-zero */
332 add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
334 Sprintf(pbuf, "Pick the race of your %s",
335 roles[flags.initrole].name.m);
337 n = select_menu(win, PICK_ONE, &selected);
338 destroy_nhwindow(win);
339 if (n != 1 || selected[0].item.a_int == any.a_int)
340 goto give_up; /* Selected quit */
341 k = selected[0].item.a_int - 1;
342 free((genericptr_t) selected), selected = 0;
348 /* Select a gender, if necessary */
349 /* force compatibility with role/race, try for compatibility with
350 * pre-selected alignment */
351 if (flags.initgend < 0
352 || !validgend(flags.initrole, flags.initrace, flags.initgend)) {
353 /* pre-selected gender not valid */
354 if (pick4u == 'y' || flags.initgend == ROLE_RANDOM
355 || flags.randomall) {
356 flags.initgend = pick_gend(flags.initrole, flags.initrace,
357 flags.initalign, PICK_RANDOM);
358 if (flags.initgend < 0) {
359 mar_add_message("Incompatible gender!");
360 mar_display_nhwindow(WIN_MESSAGE);
361 flags.initgend = randgend(flags.initrole, flags.initrace);
363 } else { /* pick4u == 'n' */
364 /* Count the number of valid genders */
365 n = 0; /* number valid */
366 k = 0; /* valid gender */
367 for (i = 0; i < ROLE_GENDERS; i++) {
368 if (ok_gend(flags.initrole, flags.initrace, i,
375 for (i = 0; i < ROLE_GENDERS; i++) {
376 if (validgend(flags.initrole, flags.initrace, i)) {
382 /* Permit the user to pick, if there is more than one */
384 win = create_nhwindow(NHW_MENU);
386 any.a_void = 0; /* zero out all bits */
387 for (i = 0; i < ROLE_GENDERS; i++)
388 if (ok_gend(flags.initrole, flags.initrace, i,
391 add_menu(win, NO_GLYPH, &any, genders[i].adj[0], 0,
392 ATR_NONE, genders[i].adj, MENU_UNSELECTED);
394 any.a_int = pick_gend(flags.initrole, flags.initrace,
395 flags.initalign, PICK_RANDOM) + 1;
396 if (any.a_int == 0) /* must be non-zero */
397 any.a_int = randgend(flags.initrole, flags.initrace) + 1;
398 add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
400 any.a_int = i + 1; /* must be non-zero */
401 add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
403 Sprintf(pbuf, "Pick the gender of your %s %s",
404 races[flags.initrace].adj,
405 roles[flags.initrole].name.m);
407 n = select_menu(win, PICK_ONE, &selected);
408 destroy_nhwindow(win);
409 if (n != 1 || selected[0].item.a_int == any.a_int)
410 goto give_up; /* Selected quit */
411 k = selected[0].item.a_int - 1;
412 free((genericptr_t) selected), selected = 0;
418 /* Select an alignment, if necessary */
419 /* force compatibility with role/race/gender */
420 if (flags.initalign < 0
421 || !validalign(flags.initrole, flags.initrace, flags.initalign)) {
422 /* pre-selected alignment not valid */
423 if (pick4u == 'y' || flags.initalign == ROLE_RANDOM
424 || flags.randomall) {
425 flags.initalign = pick_align(flags.initrole, flags.initrace,
426 flags.initgend, PICK_RANDOM);
427 if (flags.initalign < 0) {
428 mar_add_message("Incompatible alignment!");
429 mar_display_nhwindow(WIN_MESSAGE);
430 flags.initalign = randalign(flags.initrole, flags.initrace);
432 } else { /* pick4u == 'n' */
433 /* Count the number of valid alignments */
434 n = 0; /* number valid */
435 k = 0; /* valid alignment */
436 for (i = 0; i < ROLE_ALIGNS; i++) {
437 if (ok_align(flags.initrole, flags.initrace, flags.initgend,
444 for (i = 0; i < ROLE_ALIGNS; i++) {
445 if (validalign(flags.initrole, flags.initrace, i)) {
451 /* Permit the user to pick, if there is more than one */
453 win = create_nhwindow(NHW_MENU);
455 any.a_void = 0; /* zero out all bits */
456 for (i = 0; i < ROLE_ALIGNS; i++)
457 if (ok_align(flags.initrole, flags.initrace,
458 flags.initgend, i)) {
460 add_menu(win, NO_GLYPH, &any, aligns[i].adj[0], 0,
461 ATR_NONE, aligns[i].adj, MENU_UNSELECTED);
463 any.a_int = pick_align(flags.initrole, flags.initrace,
464 flags.initgend, PICK_RANDOM) + 1;
465 if (any.a_int == 0) /* must be non-zero */
466 any.a_int = randalign(flags.initrole, flags.initrace) + 1;
467 add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
469 any.a_int = i + 1; /* must be non-zero */
470 add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
472 Sprintf(pbuf, "Pick the alignment of your %s %s %s",
473 genders[flags.initgend].adj,
474 races[flags.initrace].adj,
475 (flags.initgend && roles[flags.initrole].name.f)
476 ? roles[flags.initrole].name.f
477 : roles[flags.initrole].name.m);
479 n = select_menu(win, PICK_ONE, &selected);
480 destroy_nhwindow(win);
481 if (n != 1 || selected[0].item.a_int == any.a_int)
482 goto give_up; /* Selected quit */
483 k = selected[0].item.a_int - 1;
484 free((genericptr_t) selected), selected = 0;
495 * plname is filled either by an option (-u Player or -uPlayer) or
496 * explicitly (by being the wizard) or by askname.
497 * It may still contain a suffix denoting pl_character.
498 * Always called after init_nhwindows() and before display_gamewindows().
504 strncpy(plname, mar_ask_name(), PL_NSIZ);
513 Gem_suspend_nhwindows(str)
518 foo = str; /* MAR -- And the compiler whines no more ... */
522 Gem_resume_nhwindows()
536 extern void mar_exit_nhwindows(void);
537 extern boolean run_from_desktop;
540 Gem_exit_nhwindows(str)
545 mar_exit_nhwindows();
546 if (iflags.toptenwin)
547 run_from_desktop = FALSE;
548 iflags.window_inited = 0;
552 Gem_create_nhwindow(type)
559 if (iflags.msg_history < 20)
560 iflags.msg_history = 20;
561 else if (iflags.msg_history > 60)
562 iflags.msg_history = 60;
570 panic("Tried to create window type %d\n", (int) type);
574 newid = mar_create_window(type);
576 if (newid == MAXWIN) {
577 panic("No window slots!");
593 extern void mar_clear_map(void);
596 Gem_clear_nhwindow(window)
599 if (window == WIN_ERR)
600 panic(winpanicstr, window);
602 switch (mar_hol_win_type(window)) {
604 mar_clear_messagewin();
616 extern void mar_more(void);
620 Gem_display_nhwindow(window, blocking)
624 if (window == WIN_ERR)
625 panic(winpanicstr, window);
627 mar_display_nhwindow(window);
629 switch (mar_hol_win_type(window)) {
636 Gem_display_nhwindow(WIN_MESSAGE, TRUE);
647 Gem_destroy_nhwindow(window)
650 if (window == WIN_ERR) /* MAR -- test existence */
651 panic(winpanicstr, window);
653 mar_destroy_nhwindow(window);
656 extern void mar_curs(int, int); /* mar_curs is only for map */
659 Gem_curs(window, x, y)
663 if (window == WIN_ERR) /* MAR -- test existence */
664 panic(winpanicstr, window);
666 if (window == WIN_MAP)
667 mar_curs(x - 1, y); /*$$$*/
668 else if (window == WIN_STATUS)
669 curr_status_line = y;
672 extern void mar_add_status_str(const char *, int);
673 extern void mar_putstr_text(winid, int, const char *);
676 Gem_putstr(window, attr, str)
683 if (window == WIN_ERR) {
688 if (str == (const char *) 0)
691 switch ((win_type = mar_hol_win_type(window))) {
693 mar_add_message(str);
698 mar_add_status_str(str, curr_status_line);
699 if (curr_status_line)
700 mar_display_nhwindow(WIN_STATUS);
704 if (strcmp(str, "."))
705 Gem_putstr(WIN_MESSAGE, 0, str);
707 mar_map_curs_weiter();
708 mar_display_nhwindow(WIN_MESSAGE);
709 mar_display_nhwindow(WIN_STATUS);
713 mar_change_menu_2_text(window);
716 mar_putstr_text(window, attr, str);
718 } /* endswitch win_type */
722 Gem_display_file(fname, complain)
730 f = dlb_fopen(fname, "r");
733 pline("Cannot open \"%s\".", fname);
737 datawin = Gem_create_nhwindow(NHW_TEXT);
738 while (dlb_fgets(buf, BUFSZ, f)) {
739 if ((cr = index(buf, '\n')) != 0)
741 if (index(buf, '\t') != 0)
742 (void) tabexpand(buf);
743 Gem_putstr(datawin, 0, buf);
745 (void) dlb_fclose(f);
746 Gem_display_nhwindow(datawin, FALSE);
747 Gem_destroy_nhwindow(datawin);
753 * Add a menu item to the beginning of the menu list. This list is reversed
757 Gem_add_menu(window, glyph, identifier, ch, gch, attr, str, preselected)
758 winid window; /* window to use, must be of type NHW_MENU */
759 int glyph; /* glyph to display with item (unused) */
760 const anything *identifier; /* what to return if selected */
761 char ch; /* keyboard accelerator (0 = pick our own) */
762 char gch; /* group accelerator (0 = no group) */
763 int attr; /* attribute for string (like Gem_putstr()) */
764 const char *str; /* menu string */
765 boolean preselected; /* item is marked as selected */
767 Gem_menu_item *G_item;
771 if (str == (const char *) 0)
774 if (window == WIN_ERR) /* MAR -- test existence */
775 panic(winpanicstr, window);
777 if (identifier->a_void)
778 Sprintf(buf, "%c - %s", ch ? ch : '?', str);
780 Sprintf(buf, "%s", str);
783 G_item = (Gem_menu_item *) alloc(sizeof(Gem_menu_item));
784 G_item->Gmi_identifier = (long) identifier->a_void;
785 G_item->Gmi_glyph = glyph != NO_GLYPH ? glyph2tile[glyph] : NO_GLYPH;
786 G_item->Gmi_count = -1L;
787 G_item->Gmi_selected = preselected ? 1 : 0;
788 G_item->Gmi_accelerator = ch;
789 G_item->Gmi_groupacc = gch;
790 G_item->Gmi_attr = attr;
791 G_item->Gmi_str = copy_of(newstr);
792 mar_add_menu(window, G_item);
796 * End a menu in this window, window must a type NHW_MENU.
797 * We assign the keyboard accelerators as needed.
800 Gem_end_menu(window, prompt)
801 winid window; /* menu to use */
802 const char *prompt; /* prompt to for menu */
804 if (window == WIN_ERR || mar_hol_win_type(window) != NHW_MENU)
805 panic(winpanicstr, window);
807 /* Reverse the list so that items are in correct order. */
810 /* Put the prompt at the beginning of the menu. */
811 mar_set_menu_title(prompt);
813 mar_set_accelerators();
817 Gem_select_menu(window, how, menu_list)
820 menu_item **menu_list;
826 if (window == WIN_ERR || mar_hol_win_type(window) != NHW_MENU)
827 panic(winpanicstr, window);
829 *menu_list = (menu_item *) 0;
830 mar_set_menu_type(how);
831 Gem_display_nhwindow(window, TRUE);
833 for (n = 0, Gmit = mar_hol_inv(); Gmit; Gmit = Gmit->Gmi_next)
834 if (Gmit->Gmi_selected)
838 *menu_list = (menu_item *) alloc(n * sizeof(menu_item));
839 for (mi = *menu_list, Gmit = mar_hol_inv(); Gmit;
840 Gmit = Gmit->Gmi_next)
841 if (Gmit->Gmi_selected) {
842 mi->item = (anything)(genericptr_t) Gmit->Gmi_identifier;
843 mi->count = Gmit->Gmi_count;
852 Gem_update_inventory()
859 mar_display_nhwindow(WIN_MESSAGE);
860 mar_display_nhwindow(WIN_MAP);
861 mar_display_nhwindow(WIN_STATUS);
867 mar_display_nhwindow(WIN_MESSAGE);
868 mar_display_nhwindow(WIN_MAP);
869 mar_display_nhwindow(WIN_STATUS);
873 extern void mar_cliparound(void);
881 #endif /* CLIPPING */
886 * Print the glyph to the output device. Don't flush the output device.
888 * Since this is only called from show_glyph(), it is assumed that the
889 * position and glyph are always correct (checked there)!
892 void mar_print_gl_char(winid, xchar, xchar, int);
894 extern int mar_set_rogue(int);
896 extern void mar_add_pet_sign(winid, int, int);
899 Gem_print_glyph(window, x, y, glyph, bkglyph)
904 /* Move the cursor. */
905 Gem_curs(window, x, y);
907 mar_set_rogue(Is_rogue_level(&u.uz) ? TRUE : FALSE);
909 x--; /* MAR -- because x ranges from 1 to COLNO */
910 if (mar_set_tile_mode(-1)) {
911 mar_print_glyph(window, x, y, glyph2tile[glyph], glyph2tile[bkglyph]);
917 mar_add_pet_sign(window, x, y);
919 mar_print_gl_char(window, x, y, glyph);
922 void mar_print_char(winid, xchar, xchar, char, int);
925 mar_print_gl_char(window, x, y, glyph)
934 /* map glyph to character and color */
935 (void) mapglyph(glyph, &ch, &color, &special, x, y, 0);
938 /* Turn off color if rogue level. */
939 if (Is_rogue_level(&u.uz))
941 #endif /* TEXTCOLOR */
943 mar_print_char(window, x, y, ch, color);
946 extern void mar_raw_print(const char *);
947 extern void mar_raw_print_bold(const char *);
954 if (iflags.window_inited)
962 Gem_raw_print_bold(str)
966 if (iflags.window_inited)
967 mar_raw_print_bold(str);
973 extern void mar_update_value(void); /* wingem1.c */
983 i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */
988 /* Get a extended command in windowport specific way.
989 returns index of the ext_cmd or -1.
991 It's a menu with all the possibilities. */
996 int i, count, what, too_much = FALSE;
997 menu_item *selected = NULL;
999 char accelerator = 0, tmp_acc = 0;
1002 wind = Gem_create_nhwindow(NHW_MENU);
1003 Gem_start_menu(wind);
1004 for (i = 0; (ptr = extcmdlist[i].ef_txt); i++) {
1007 if (tmp_acc == accelerator) {
1009 accelerator = '&'; /* MAR -- poor choice, anyone? */
1011 accelerator += 'A' - 'a';
1016 Gem_add_menu(wind, NO_GLYPH, &any, accelerator, 0, ATR_NONE, ptr,
1019 Gem_end_menu(wind, "What extended command?");
1020 count = Gem_select_menu(wind, PICK_ONE, &selected);
1021 what = count ? selected->item.a_int : -1;
1024 Gem_destroy_nhwindow(wind);
1029 Gem_number_pad(state)
1042 Gem_update_positionbar(posbar)
1049 void mar_set_text_to_rip(winid);
1050 char **rip_line = 0;
1053 Gem_outrip(w, how, when)
1058 /* Code from X11 windowport */
1059 #define STONE_LINE_LEN 15 /* # chars that fit on one line */
1060 #define NAME_LINE 0 /* line # for player name */
1061 #define GOLD_LINE 1 /* line # for amount of gold */
1062 #define DEATH_LINE 2 /* line # for death description */
1063 #define YEAR_LINE 6 /* line # for year */
1071 rip_line = (char **) malloc((YEAR_LINE + 1) * sizeof(char *));
1072 for (i = 0; i < YEAR_LINE + 1; i++) {
1074 (char *) malloc((STONE_LINE_LEN + 1) * sizeof(char));
1077 /* Follows same algorithm as genl_outrip() */
1078 /* Put name on stone */
1079 Sprintf(rip_line[NAME_LINE], "%s", plname);
1080 /* Put $ on stone */
1081 Sprintf(rip_line[GOLD_LINE], "%ld Au", done_money);
1082 /* Put together death description */
1083 formatkiller(buf, sizeof buf, how, FALSE);
1085 /* Put death type on stone */
1086 for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) {
1089 if ((i0 = strlen(dpx)) > STONE_LINE_LEN) {
1090 for (i = STONE_LINE_LEN; ((i0 > STONE_LINE_LEN) && i); i--)
1094 i0 = STONE_LINE_LEN;
1098 strcpy(rip_line[line], dpx);
1099 if (tmpchar != ' ') {
1105 /* Put year on stone */
1106 year = yyyymmdd(when) / 10000L;
1107 Sprintf(rip_line[YEAR_LINE], "%4ld", year);
1109 mar_set_text_to_rip(w);
1110 for (line = 0; line < 13; line++)
1114 mar_get_font(type, p_fname, psize)
1121 *p_fname = iflags.wc_font_message;
1122 *psize = iflags.wc_fontsiz_message;
1125 *p_fname = iflags.wc_font_map;
1126 *psize = iflags.wc_fontsiz_map;
1129 *p_fname = iflags.wc_font_status;
1130 *psize = iflags.wc_fontsiz_status;
1133 *p_fname = iflags.wc_font_menu;
1134 *psize = iflags.wc_fontsiz_menu;
1137 *p_fname = iflags.wc_font_text;
1138 *psize = iflags.wc_fontsiz_text;
1145 Gem_preference_update(pref)
1148 if (stricmp(pref, "font_message") == 0
1149 || stricmp(pref, "font_size_message") == 0) {
1150 if (iflags.wc_fontsiz_message < NHFONT_SIZE_MIN
1151 || iflags.wc_fontsiz_message > NHFONT_SIZE_MAX)
1152 iflags.wc_fontsiz_message = NHFONT_DEFAULT_SIZE;
1153 mar_set_font(NHW_MESSAGE, iflags.wc_font_message,
1154 iflags.wc_fontsiz_message);
1157 if (stricmp(pref, "font_map") == 0
1158 || stricmp(pref, "font_size_map") == 0) {
1159 if (iflags.wc_fontsiz_map < NHFONT_SIZE_MIN
1160 || iflags.wc_fontsiz_map > NHFONT_SIZE_MAX)
1161 iflags.wc_fontsiz_map = NHFONT_DEFAULT_SIZE;
1162 mar_set_font(NHW_MAP, iflags.wc_font_map, iflags.wc_fontsiz_map);
1165 if (stricmp(pref, "font_status") == 0
1166 || stricmp(pref, "font_size_status") == 0) {
1167 if (iflags.wc_fontsiz_status < NHFONT_SIZE_MIN
1168 || iflags.wc_fontsiz_status > NHFONT_SIZE_MAX)
1169 iflags.wc_fontsiz_status = NHFONT_DEFAULT_SIZE;
1170 mar_set_font(NHW_STATUS, iflags.wc_font_status,
1171 iflags.wc_fontsiz_status);
1174 if (stricmp(pref, "font_menu") == 0
1175 || stricmp(pref, "font_size_menu") == 0) {
1176 if (iflags.wc_fontsiz_menu < NHFONT_SIZE_MIN
1177 || iflags.wc_fontsiz_menu > NHFONT_SIZE_MAX)
1178 iflags.wc_fontsiz_menu = NHFONT_DEFAULT_SIZE;
1179 mar_set_font(NHW_MENU, iflags.wc_font_menu, iflags.wc_fontsiz_menu);
1182 if (stricmp(pref, "font_text") == 0
1183 || stricmp(pref, "font_size_text") == 0) {
1184 if (iflags.wc_fontsiz_text < NHFONT_SIZE_MIN
1185 || iflags.wc_fontsiz_text > NHFONT_SIZE_MAX)
1186 iflags.wc_fontsiz_text = NHFONT_DEFAULT_SIZE;
1187 mar_set_font(NHW_TEXT, iflags.wc_font_text, iflags.wc_fontsiz_text);
1190 if (stricmp(pref, "scroll_margin") == 0) {
1191 mar_set_margin(iflags.wc_scroll_margin);
1192 Gem_cliparound(u.ux, u.uy);
1195 if (stricmp(pref, "ascii_map") == 0) {
1196 mar_set_tile_mode(!iflags.wc_ascii_map);
1200 if (stricmp(pref, "hilite_pet") == 0) {
1201 /* MAR -- works without doing something here. */
1204 if (stricmp(pref, "align_message") == 0) {
1205 mar_set_msg_align(iflags.wc_align_message - ALIGN_BOTTOM);
1208 if (stricmp(pref, "align_status") == 0) {
1209 mar_set_status_align(iflags.wc_align_status - ALIGN_BOTTOM);
1212 if (stricmp(pref, "vary_msgcount") == 0) {
1213 mar_set_msg_visible(iflags.wc_vary_msgcount);
1218 * Allocate a copy of the given string. If null, return a string of
1221 * This is an exact duplicate of copy_of() in X11/winmenu.c.
1229 return strcpy((char *) alloc((unsigned) (strlen(s) + 1)), s);
1232 #endif /* GEM_GRAPHICS \