1 /* aNetHack 0.0.1 wingem.c $ANH-Date: 1450453304 2015/12/18 15:41:44 $ $ANH-Branch: aNetHack-3.6.0 $:$ANH-Revision: 1.26 $ */
2 /* Copyright (c) Christian Bressler, 1999 */
3 /* aNetHack 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
,
46 0L, Gem_init_nhwindows
, Gem_player_selection
, Gem_askname
,
47 Gem_get_nh_event
, Gem_exit_nhwindows
, Gem_suspend_nhwindows
,
48 Gem_resume_nhwindows
, Gem_create_nhwindow
, Gem_clear_nhwindow
,
49 Gem_display_nhwindow
, Gem_destroy_nhwindow
, Gem_curs
, Gem_putstr
,
50 genl_putmixed
, Gem_display_file
, Gem_start_menu
, Gem_add_menu
,
51 Gem_end_menu
, Gem_select_menu
, genl_message_menu
, Gem_update_inventory
,
52 Gem_mark_synch
, Gem_wait_synch
,
57 Gem_update_positionbar
,
59 Gem_print_glyph
, Gem_raw_print
, Gem_raw_print_bold
, Gem_nhgetch
,
60 Gem_nh_poskey
, Gem_nhbell
, Gem_doprev_message
, Gem_yn_function
,
61 Gem_getlin
, Gem_get_ext_cmd
, Gem_number_pad
, Gem_delay_output
,
62 #ifdef CHANGE_COLOR /* the Mac uses a palette device */
65 Gem_change_background
, Gem_set_font_name
,
70 /* other defs that really should go away (they're tty specific) */
71 Gem_start_screen
, Gem_end_screen
, Gem_outrip
, Gem_preference_update
,
72 genl_getmsghistory
, genl_putmsghistory
73 #ifdef STATUS_VIA_WINDOWPORT
75 genl_status_finish
, genl_status_enablefield
, genl_status_update
,
77 genl_status_threshold
,
85 Gem_change_background(dummy
)
91 Gem_set_font_name(foo
, bar
)
98 /*************************** Proceduren *************************************/
104 return (u
.mh
? u
.mhmax
/ u
.mh
: -1);
105 return (u
.uhp
? u
.uhpmax
/ u
.uhp
: -1);
111 return (iflags
.num_pad
? 1 : 0);
115 mar_get_msg_history()
117 return (iflags
.msg_history
);
121 mar_get_msg_visible()
123 return (iflags
.wc_vary_msgcount
);
125 /* clean up and quit */
131 Gem_exit_nhwindows(mesg
);
132 terminate(EXIT_SUCCESS
);
137 #define DEF_CLIPAROUND_MARGIN -1
142 #define TILES_PER_LINE 20
143 #define NHFONT_DEFAULT_SIZE 10
144 #define NHFONT_SIZE_MIN 3
145 #define NHFONT_SIZE_MAX 20
149 Gem_init_nhwindows(argcp
, argv
)
153 argv
= argv
, argcp
= argcp
;
154 colors_changed
= TRUE
;
156 set_wc_option_mod_status(WC_ALIGN_MESSAGE
| WC_ALIGN_STATUS
157 | WC_TILE_WIDTH
| WC_TILE_HEIGHT
160 set_wc_option_mod_status(
161 WC_HILITE_PET
| WC_SCROLL_MARGIN
| WC_FONT_MESSAGE
| WC_FONT_MAP
162 | WC_FONT_STATUS
| WC_FONT_MENU
| WC_FONT_TEXT
163 | WC_FONTSIZ_MESSAGE
| WC_FONTSIZ_MAP
| WC_FONTSIZ_STATUS
164 | WC_FONTSIZ_MENU
| WC_FONTSIZ_TEXT
| WC_VARY_MSGCOUNT
,
166 if (iflags
.wc_align_message
== 0)
167 iflags
.wc_align_message
= ALIGN_TOP
;
168 if (iflags
.wc_align_status
== 0)
169 iflags
.wc_align_status
= ALIGN_BOTTOM
;
170 if (iflags
.wc_scroll_margin
== 0)
171 iflags
.wc_scroll_margin
= DEF_CLIPAROUND_MARGIN
;
172 if (iflags
.wc_tile_width
== 0)
173 iflags
.wc_tile_width
= TILE_X
;
174 if (iflags
.wc_tile_height
== 0)
175 iflags
.wc_tile_height
= TILE_Y
;
176 if (iflags
.wc_tile_file
&& *iflags
.wc_tile_file
)
177 mar_set_tilefile(iflags
.wc_tile_file
);
178 if (iflags
.wc_vary_msgcount
== 0)
179 iflags
.wc_vary_msgcount
= 3;
181 !iflags
.wc_ascii_map
); /* MAR -- 17.Mar 2002 True is tiles */
182 mar_set_tilex(iflags
.wc_tile_width
);
183 mar_set_tiley(iflags
.wc_tile_height
);
184 mar_set_msg_align(iflags
.wc_align_message
- ALIGN_BOTTOM
);
185 mar_set_status_align(iflags
.wc_align_status
- ALIGN_BOTTOM
);
186 if (mar_gem_init() == 0) {
190 iflags
.window_inited
= TRUE
;
192 CO
= 80; /* MAR -- whatsoever */
195 add_menu_cmd_alias(' ', MENU_NEXT_PAGE
);
196 mar_set_no_glyph(NO_GLYPH
);
200 Gem_player_selection()
203 char pick4u
= 'n', pbuf
[QBUFSZ
], lastch
= 0, currch
;
206 menu_item
*selected
= NULL
;
208 /* avoid unnecessary prompts further down */
211 /* Should we randomly pick for the player? */
213 && (flags
.initrole
== ROLE_NONE
|| flags
.initrace
== ROLE_NONE
214 || flags
.initgend
== ROLE_NONE
|| flags
.initalign
== ROLE_NONE
)) {
215 /* pick4u = yn_function("Shall I pick a character for you?
216 * [ynq]",ynqchars,'n');*/
217 pick4u
= yn_function(build_plselection_prompt(
218 pbuf
, QBUFSZ
, flags
.initrole
, flags
.initrace
,
219 flags
.initgend
, flags
.initalign
),
222 give_up
: /* Just quit */
224 free((genericptr_t
) selected
);
231 /* Select a role, if necessary */
232 if (flags
.initrole
< 0) {
233 /* Process the choice */
234 if (pick4u
== 'y' || flags
.initrole
== ROLE_RANDOM
235 || flags
.randomall
) {
236 /* Pick a random role */
237 flags
.initrole
= pick_role(flags
.initrace
, flags
.initgend
,
238 flags
.initalign
, PICK_RANDOM
);
239 if (flags
.initrole
< 0) {
240 mar_add_message("Incompatible role!");
241 mar_display_nhwindow(WIN_MESSAGE
);
242 flags
.initrole
= randrole();
245 /* Prompt for a role */
246 win
= create_nhwindow(NHW_MENU
);
248 any
.a_void
= 0; /* zero out all bits */
249 for (i
= 0; roles
[i
].name
.m
; i
++) {
250 if (ok_role(i
, flags
.initrace
, flags
.initgend
,
252 any
.a_int
= i
+ 1; /* must be non-zero */
253 currch
= lowc(roles
[i
].name
.m
[0]);
254 if (currch
== lastch
)
255 currch
= highc(currch
);
256 add_menu(win
, roles
[i
].malenum
, &any
, currch
, 0, ATR_NONE
,
257 an(roles
[i
].name
.m
), MENU_UNSELECTED
);
261 any
.a_int
= pick_role(flags
.initrace
, flags
.initgend
,
262 flags
.initalign
, PICK_RANDOM
) + 1;
263 if (any
.a_int
== 0) /* must be non-zero */
264 any
.a_int
= randrole() + 1;
265 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
267 any
.a_int
= i
+ 1; /* must be non-zero */
268 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
270 end_menu(win
, "Pick a role");
271 n
= select_menu(win
, PICK_ONE
, &selected
);
272 destroy_nhwindow(win
);
274 /* Process the choice */
275 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
276 goto give_up
; /* Selected quit */
278 flags
.initrole
= selected
[0].item
.a_int
- 1;
279 free((genericptr_t
) selected
), selected
= 0;
283 /* Select a race, if necessary */
284 /* force compatibility with role, try for compatibility with
285 * pre-selected gender/alignment */
286 if (flags
.initrace
< 0 || !validrace(flags
.initrole
, flags
.initrace
)) {
287 /* pre-selected race not valid */
288 if (pick4u
== 'y' || flags
.initrace
== ROLE_RANDOM
289 || flags
.randomall
) {
290 flags
.initrace
= pick_race(flags
.initrole
, flags
.initgend
,
291 flags
.initalign
, PICK_RANDOM
);
292 if (flags
.initrace
< 0) {
293 mar_add_message("Incompatible race!");
294 mar_display_nhwindow(WIN_MESSAGE
);
295 flags
.initrace
= randrace(flags
.initrole
);
297 } else { /* pick4u == 'n' */
298 /* Count the number of valid races */
299 n
= 0; /* number valid */
300 k
= 0; /* valid race */
301 for (i
= 0; races
[i
].noun
; i
++) {
302 if (ok_race(flags
.initrole
, i
, flags
.initgend
,
309 for (i
= 0; races
[i
].noun
; i
++) {
310 if (validrace(flags
.initrole
, i
)) {
316 /* Permit the user to pick, if there is more than one */
318 win
= create_nhwindow(NHW_MENU
);
320 any
.a_void
= 0; /* zero out all bits */
321 for (i
= 0; races
[i
].noun
; i
++)
322 if (ok_race(flags
.initrole
, i
, flags
.initgend
,
324 any
.a_int
= i
+ 1; /* must be non-zero */
325 add_menu(win
, NO_GLYPH
, &any
, races
[i
].noun
[0], 0,
326 ATR_NONE
, races
[i
].noun
, MENU_UNSELECTED
);
328 any
.a_int
= pick_race(flags
.initrole
, flags
.initgend
,
329 flags
.initalign
, PICK_RANDOM
) + 1;
330 if (any
.a_int
== 0) /* must be non-zero */
331 any
.a_int
= randrace(flags
.initrole
) + 1;
332 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
334 any
.a_int
= i
+ 1; /* must be non-zero */
335 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
337 Sprintf(pbuf
, "Pick the race of your %s",
338 roles
[flags
.initrole
].name
.m
);
340 n
= select_menu(win
, PICK_ONE
, &selected
);
341 destroy_nhwindow(win
);
342 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
343 goto give_up
; /* Selected quit */
344 k
= selected
[0].item
.a_int
- 1;
345 free((genericptr_t
) selected
), selected
= 0;
351 /* Select a gender, if necessary */
352 /* force compatibility with role/race, try for compatibility with
353 * pre-selected alignment */
354 if (flags
.initgend
< 0
355 || !validgend(flags
.initrole
, flags
.initrace
, flags
.initgend
)) {
356 /* pre-selected gender not valid */
357 if (pick4u
== 'y' || flags
.initgend
== ROLE_RANDOM
358 || flags
.randomall
) {
359 flags
.initgend
= pick_gend(flags
.initrole
, flags
.initrace
,
360 flags
.initalign
, PICK_RANDOM
);
361 if (flags
.initgend
< 0) {
362 mar_add_message("Incompatible gender!");
363 mar_display_nhwindow(WIN_MESSAGE
);
364 flags
.initgend
= randgend(flags
.initrole
, flags
.initrace
);
366 } else { /* pick4u == 'n' */
367 /* Count the number of valid genders */
368 n
= 0; /* number valid */
369 k
= 0; /* valid gender */
370 for (i
= 0; i
< ROLE_GENDERS
; i
++) {
371 if (ok_gend(flags
.initrole
, flags
.initrace
, i
,
378 for (i
= 0; i
< ROLE_GENDERS
; i
++) {
379 if (validgend(flags
.initrole
, flags
.initrace
, i
)) {
385 /* Permit the user to pick, if there is more than one */
387 win
= create_nhwindow(NHW_MENU
);
389 any
.a_void
= 0; /* zero out all bits */
390 for (i
= 0; i
< ROLE_GENDERS
; i
++)
391 if (ok_gend(flags
.initrole
, flags
.initrace
, i
,
394 add_menu(win
, NO_GLYPH
, &any
, genders
[i
].adj
[0], 0,
395 ATR_NONE
, genders
[i
].adj
, MENU_UNSELECTED
);
397 any
.a_int
= pick_gend(flags
.initrole
, flags
.initrace
,
398 flags
.initalign
, PICK_RANDOM
) + 1;
399 if (any
.a_int
== 0) /* must be non-zero */
400 any
.a_int
= randgend(flags
.initrole
, flags
.initrace
) + 1;
401 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
403 any
.a_int
= i
+ 1; /* must be non-zero */
404 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
406 Sprintf(pbuf
, "Pick the gender of your %s %s",
407 races
[flags
.initrace
].adj
,
408 roles
[flags
.initrole
].name
.m
);
410 n
= select_menu(win
, PICK_ONE
, &selected
);
411 destroy_nhwindow(win
);
412 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
413 goto give_up
; /* Selected quit */
414 k
= selected
[0].item
.a_int
- 1;
415 free((genericptr_t
) selected
), selected
= 0;
421 /* Select an alignment, if necessary */
422 /* force compatibility with role/race/gender */
423 if (flags
.initalign
< 0
424 || !validalign(flags
.initrole
, flags
.initrace
, flags
.initalign
)) {
425 /* pre-selected alignment not valid */
426 if (pick4u
== 'y' || flags
.initalign
== ROLE_RANDOM
427 || flags
.randomall
) {
428 flags
.initalign
= pick_align(flags
.initrole
, flags
.initrace
,
429 flags
.initgend
, PICK_RANDOM
);
430 if (flags
.initalign
< 0) {
431 mar_add_message("Incompatible alignment!");
432 mar_display_nhwindow(WIN_MESSAGE
);
433 flags
.initalign
= randalign(flags
.initrole
, flags
.initrace
);
435 } else { /* pick4u == 'n' */
436 /* Count the number of valid alignments */
437 n
= 0; /* number valid */
438 k
= 0; /* valid alignment */
439 for (i
= 0; i
< ROLE_ALIGNS
; i
++) {
440 if (ok_align(flags
.initrole
, flags
.initrace
, flags
.initgend
,
447 for (i
= 0; i
< ROLE_ALIGNS
; i
++) {
448 if (validalign(flags
.initrole
, flags
.initrace
, i
)) {
454 /* Permit the user to pick, if there is more than one */
456 win
= create_nhwindow(NHW_MENU
);
458 any
.a_void
= 0; /* zero out all bits */
459 for (i
= 0; i
< ROLE_ALIGNS
; i
++)
460 if (ok_align(flags
.initrole
, flags
.initrace
,
461 flags
.initgend
, i
)) {
463 add_menu(win
, NO_GLYPH
, &any
, aligns
[i
].adj
[0], 0,
464 ATR_NONE
, aligns
[i
].adj
, MENU_UNSELECTED
);
466 any
.a_int
= pick_align(flags
.initrole
, flags
.initrace
,
467 flags
.initgend
, PICK_RANDOM
) + 1;
468 if (any
.a_int
== 0) /* must be non-zero */
469 any
.a_int
= randalign(flags
.initrole
, flags
.initrace
) + 1;
470 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
472 any
.a_int
= i
+ 1; /* must be non-zero */
473 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
475 Sprintf(pbuf
, "Pick the alignment of your %s %s %s",
476 genders
[flags
.initgend
].adj
,
477 races
[flags
.initrace
].adj
,
478 (flags
.initgend
&& roles
[flags
.initrole
].name
.f
)
479 ? roles
[flags
.initrole
].name
.f
480 : roles
[flags
.initrole
].name
.m
);
482 n
= select_menu(win
, PICK_ONE
, &selected
);
483 destroy_nhwindow(win
);
484 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
485 goto give_up
; /* Selected quit */
486 k
= selected
[0].item
.a_int
- 1;
487 free((genericptr_t
) selected
), selected
= 0;
498 * plname is filled either by an option (-u Player or -uPlayer) or
499 * explicitly (by being the wizard) or by askname.
500 * It may still contain a suffix denoting pl_character.
501 * Always called after init_nhwindows() and before display_gamewindows().
507 strncpy(plname
, mar_ask_name(), PL_NSIZ
);
516 Gem_suspend_nhwindows(str
)
521 foo
= str
; /* MAR -- And the compiler whines no more ... */
525 Gem_resume_nhwindows()
539 extern void mar_exit_nhwindows(void);
540 extern boolean run_from_desktop
;
543 Gem_exit_nhwindows(str
)
548 mar_exit_nhwindows();
549 if (iflags
.toptenwin
)
550 run_from_desktop
= FALSE
;
551 iflags
.window_inited
= 0;
555 Gem_create_nhwindow(type
)
562 if (iflags
.msg_history
< 20)
563 iflags
.msg_history
= 20;
564 else if (iflags
.msg_history
> 60)
565 iflags
.msg_history
= 60;
573 panic("Tried to create window type %d\n", (int) type
);
577 newid
= mar_create_window(type
);
579 if (newid
== MAXWIN
) {
580 panic("No window slots!");
596 extern void mar_clear_map(void);
599 Gem_clear_nhwindow(window
)
602 if (window
== WIN_ERR
)
603 panic(winpanicstr
, window
);
605 switch (mar_hol_win_type(window
)) {
607 mar_clear_messagewin();
619 extern void mar_more(void);
623 Gem_display_nhwindow(window
, blocking
)
627 if (window
== WIN_ERR
)
628 panic(winpanicstr
, window
);
630 mar_display_nhwindow(window
);
632 switch (mar_hol_win_type(window
)) {
639 Gem_display_nhwindow(WIN_MESSAGE
, TRUE
);
650 Gem_destroy_nhwindow(window
)
653 if (window
== WIN_ERR
) /* MAR -- test existence */
654 panic(winpanicstr
, window
);
656 mar_destroy_nhwindow(window
);
659 extern void mar_curs(int, int); /* mar_curs is only for map */
662 Gem_curs(window
, x
, y
)
666 if (window
== WIN_ERR
) /* MAR -- test existence */
667 panic(winpanicstr
, window
);
669 if (window
== WIN_MAP
)
670 mar_curs(x
- 1, y
); /*$$$*/
671 else if (window
== WIN_STATUS
)
672 curr_status_line
= y
;
675 extern void mar_add_status_str(const char *, int);
676 extern void mar_putstr_text(winid
, int, const char *);
679 Gem_putstr(window
, attr
, str
)
686 if (window
== WIN_ERR
) {
691 if (str
== (const char *) 0)
694 switch ((win_type
= mar_hol_win_type(window
))) {
696 mar_add_message(str
);
701 mar_add_status_str(str
, curr_status_line
);
702 if (curr_status_line
)
703 mar_display_nhwindow(WIN_STATUS
);
707 if (strcmp(str
, "."))
708 Gem_putstr(WIN_MESSAGE
, 0, str
);
710 mar_map_curs_weiter();
711 mar_display_nhwindow(WIN_MESSAGE
);
712 mar_display_nhwindow(WIN_STATUS
);
716 mar_change_menu_2_text(window
);
719 mar_putstr_text(window
, attr
, str
);
721 } /* endswitch win_type */
725 Gem_display_file(fname
, complain
)
733 f
= dlb_fopen(fname
, "r");
736 pline("Cannot open \"%s\".", fname
);
740 datawin
= Gem_create_nhwindow(NHW_TEXT
);
741 while (dlb_fgets(buf
, BUFSZ
, f
)) {
742 if ((cr
= index(buf
, '\n')) != 0)
744 if (index(buf
, '\t') != 0)
745 (void) tabexpand(buf
);
746 Gem_putstr(datawin
, 0, buf
);
748 (void) dlb_fclose(f
);
749 Gem_display_nhwindow(datawin
, FALSE
);
750 Gem_destroy_nhwindow(datawin
);
756 * Add a menu item to the beginning of the menu list. This list is reversed
760 Gem_add_menu(window
, glyph
, identifier
, ch
, gch
, attr
, str
, preselected
)
761 winid window
; /* window to use, must be of type NHW_MENU */
762 int glyph
; /* glyph to display with item (unused) */
763 const anything
*identifier
; /* what to return if selected */
764 char ch
; /* keyboard accelerator (0 = pick our own) */
765 char gch
; /* group accelerator (0 = no group) */
766 int attr
; /* attribute for string (like Gem_putstr()) */
767 const char *str
; /* menu string */
768 boolean preselected
; /* item is marked as selected */
770 Gem_menu_item
*G_item
;
774 if (str
== (const char *) 0)
777 if (window
== WIN_ERR
) /* MAR -- test existence */
778 panic(winpanicstr
, window
);
780 if (identifier
->a_void
)
781 Sprintf(buf
, "%c - %s", ch
? ch
: '?', str
);
783 Sprintf(buf
, "%s", str
);
786 G_item
= (Gem_menu_item
*) alloc(sizeof(Gem_menu_item
));
787 G_item
->Gmi_identifier
= (long) identifier
->a_void
;
788 G_item
->Gmi_glyph
= glyph
!= NO_GLYPH
? glyph2tile
[glyph
] : NO_GLYPH
;
789 G_item
->Gmi_count
= -1L;
790 G_item
->Gmi_selected
= preselected
? 1 : 0;
791 G_item
->Gmi_accelerator
= ch
;
792 G_item
->Gmi_groupacc
= gch
;
793 G_item
->Gmi_attr
= attr
;
794 G_item
->Gmi_str
= copy_of(newstr
);
795 mar_add_menu(window
, G_item
);
799 * End a menu in this window, window must a type NHW_MENU.
800 * We assign the keyboard accelerators as needed.
803 Gem_end_menu(window
, prompt
)
804 winid window
; /* menu to use */
805 const char *prompt
; /* prompt to for menu */
807 if (window
== WIN_ERR
|| mar_hol_win_type(window
) != NHW_MENU
)
808 panic(winpanicstr
, window
);
810 /* Reverse the list so that items are in correct order. */
813 /* Put the prompt at the beginning of the menu. */
814 mar_set_menu_title(prompt
);
816 mar_set_accelerators();
820 Gem_select_menu(window
, how
, menu_list
)
823 menu_item
**menu_list
;
829 if (window
== WIN_ERR
|| mar_hol_win_type(window
) != NHW_MENU
)
830 panic(winpanicstr
, window
);
832 *menu_list
= (menu_item
*) 0;
833 mar_set_menu_type(how
);
834 Gem_display_nhwindow(window
, TRUE
);
836 for (n
= 0, Gmit
= mar_hol_inv(); Gmit
; Gmit
= Gmit
->Gmi_next
)
837 if (Gmit
->Gmi_selected
)
841 *menu_list
= (menu_item
*) alloc(n
* sizeof(menu_item
));
842 for (mi
= *menu_list
, Gmit
= mar_hol_inv(); Gmit
;
843 Gmit
= Gmit
->Gmi_next
)
844 if (Gmit
->Gmi_selected
) {
845 mi
->item
= (anything
)(genericptr_t
) Gmit
->Gmi_identifier
;
846 mi
->count
= Gmit
->Gmi_count
;
855 Gem_update_inventory()
862 mar_display_nhwindow(WIN_MESSAGE
);
863 mar_display_nhwindow(WIN_MAP
);
864 mar_display_nhwindow(WIN_STATUS
);
870 mar_display_nhwindow(WIN_MESSAGE
);
871 mar_display_nhwindow(WIN_MAP
);
872 mar_display_nhwindow(WIN_STATUS
);
876 extern void mar_cliparound(void);
884 #endif /* CLIPPING */
889 * Print the glyph to the output device. Don't flush the output device.
891 * Since this is only called from show_glyph(), it is assumed that the
892 * position and glyph are always correct (checked there)!
895 void mar_print_gl_char(winid
, xchar
, xchar
, int);
897 extern int mar_set_rogue(int);
899 extern void mar_add_pet_sign(winid
, int, int);
902 Gem_print_glyph(window
, x
, y
, glyph
, bkglyph
)
907 /* Move the cursor. */
908 Gem_curs(window
, x
, y
);
910 mar_set_rogue(Is_rogue_level(&u
.uz
) ? TRUE
: FALSE
);
912 x
--; /* MAR -- because x ranges from 1 to COLNO */
913 if (mar_set_tile_mode(-1)) {
914 mar_print_glyph(window
, x
, y
, glyph2tile
[glyph
], glyph2tile
[bkglyph
]);
920 mar_add_pet_sign(window
, x
, y
);
922 mar_print_gl_char(window
, x
, y
, glyph
);
925 void mar_print_char(winid
, xchar
, xchar
, char, int);
928 mar_print_gl_char(window
, x
, y
, glyph
)
937 /* map glyph to character and color */
938 (void) mapglyph(glyph
, &ch
, &color
, &special
, x
, y
);
941 /* Turn off color if rogue level. */
942 if (Is_rogue_level(&u
.uz
))
944 #endif /* TEXTCOLOR */
946 mar_print_char(window
, x
, y
, ch
, color
);
949 extern void mar_raw_print(const char *);
950 extern void mar_raw_print_bold(const char *);
957 if (iflags
.window_inited
)
965 Gem_raw_print_bold(str
)
969 if (iflags
.window_inited
)
970 mar_raw_print_bold(str
);
976 extern void mar_update_value(void); /* wingem1.c */
986 i
= '\033'; /* map NUL to ESC since anethack doesn't expect NUL */
991 /* Get a extended command in windowport specific way.
992 returns index of the ext_cmd or -1.
994 It's a menu with all the possibilities. */
999 int i
, count
, what
, too_much
= FALSE
;
1000 menu_item
*selected
= NULL
;
1002 char accelerator
= 0, tmp_acc
= 0;
1005 wind
= Gem_create_nhwindow(NHW_MENU
);
1006 Gem_start_menu(wind
);
1007 for (i
= 0; (ptr
= extcmdlist
[i
].ef_txt
); i
++) {
1010 if (tmp_acc
== accelerator
) {
1012 accelerator
= '&'; /* MAR -- poor choice, anyone? */
1014 accelerator
+= 'A' - 'a';
1019 Gem_add_menu(wind
, NO_GLYPH
, &any
, accelerator
, 0, ATR_NONE
, ptr
,
1022 Gem_end_menu(wind
, "What extended command?");
1023 count
= Gem_select_menu(wind
, PICK_ONE
, &selected
);
1024 what
= count
? selected
->item
.a_int
: -1;
1027 Gem_destroy_nhwindow(wind
);
1032 Gem_number_pad(state
)
1045 Gem_update_positionbar(posbar
)
1052 void mar_set_text_to_rip(winid
);
1053 char **rip_line
= 0;
1056 Gem_outrip(w
, how
, when
)
1061 /* Code from X11 windowport */
1062 #define STONE_LINE_LEN 15 /* # chars that fit on one line */
1063 #define NAME_LINE 0 /* line # for player name */
1064 #define GOLD_LINE 1 /* line # for amount of gold */
1065 #define DEATH_LINE 2 /* line # for death description */
1066 #define YEAR_LINE 6 /* line # for year */
1074 rip_line
= (char **) malloc((YEAR_LINE
+ 1) * sizeof(char *));
1075 for (i
= 0; i
< YEAR_LINE
+ 1; i
++) {
1077 (char *) malloc((STONE_LINE_LEN
+ 1) * sizeof(char));
1080 /* Follows same algorithm as genl_outrip() */
1081 /* Put name on stone */
1082 Sprintf(rip_line
[NAME_LINE
], "%s", plname
);
1083 /* Put $ on stone */
1084 Sprintf(rip_line
[GOLD_LINE
], "%ld Au", done_money
);
1085 /* Put together death description */
1086 formatkiller(buf
, sizeof buf
, how
, FALSE
);
1088 /* Put death type on stone */
1089 for (line
= DEATH_LINE
, dpx
= buf
; line
< YEAR_LINE
; line
++) {
1092 if ((i0
= strlen(dpx
)) > STONE_LINE_LEN
) {
1093 for (i
= STONE_LINE_LEN
; ((i0
> STONE_LINE_LEN
) && i
); i
--)
1097 i0
= STONE_LINE_LEN
;
1101 strcpy(rip_line
[line
], dpx
);
1102 if (tmpchar
!= ' ') {
1108 /* Put year on stone */
1109 year
= yyyymmdd(when
) / 10000L;
1110 Sprintf(rip_line
[YEAR_LINE
], "%4ld", year
);
1112 mar_set_text_to_rip(w
);
1113 for (line
= 0; line
< 13; line
++)
1117 mar_get_font(type
, p_fname
, psize
)
1124 *p_fname
= iflags
.wc_font_message
;
1125 *psize
= iflags
.wc_fontsiz_message
;
1128 *p_fname
= iflags
.wc_font_map
;
1129 *psize
= iflags
.wc_fontsiz_map
;
1132 *p_fname
= iflags
.wc_font_status
;
1133 *psize
= iflags
.wc_fontsiz_status
;
1136 *p_fname
= iflags
.wc_font_menu
;
1137 *psize
= iflags
.wc_fontsiz_menu
;
1140 *p_fname
= iflags
.wc_font_text
;
1141 *psize
= iflags
.wc_fontsiz_text
;
1148 Gem_preference_update(pref
)
1151 if (stricmp(pref
, "font_message") == 0
1152 || stricmp(pref
, "font_size_message") == 0) {
1153 if (iflags
.wc_fontsiz_message
< NHFONT_SIZE_MIN
1154 || iflags
.wc_fontsiz_message
> NHFONT_SIZE_MAX
)
1155 iflags
.wc_fontsiz_message
= NHFONT_DEFAULT_SIZE
;
1156 mar_set_font(NHW_MESSAGE
, iflags
.wc_font_message
,
1157 iflags
.wc_fontsiz_message
);
1160 if (stricmp(pref
, "font_map") == 0
1161 || stricmp(pref
, "font_size_map") == 0) {
1162 if (iflags
.wc_fontsiz_map
< NHFONT_SIZE_MIN
1163 || iflags
.wc_fontsiz_map
> NHFONT_SIZE_MAX
)
1164 iflags
.wc_fontsiz_map
= NHFONT_DEFAULT_SIZE
;
1165 mar_set_font(NHW_MAP
, iflags
.wc_font_map
, iflags
.wc_fontsiz_map
);
1168 if (stricmp(pref
, "font_status") == 0
1169 || stricmp(pref
, "font_size_status") == 0) {
1170 if (iflags
.wc_fontsiz_status
< NHFONT_SIZE_MIN
1171 || iflags
.wc_fontsiz_status
> NHFONT_SIZE_MAX
)
1172 iflags
.wc_fontsiz_status
= NHFONT_DEFAULT_SIZE
;
1173 mar_set_font(NHW_STATUS
, iflags
.wc_font_status
,
1174 iflags
.wc_fontsiz_status
);
1177 if (stricmp(pref
, "font_menu") == 0
1178 || stricmp(pref
, "font_size_menu") == 0) {
1179 if (iflags
.wc_fontsiz_menu
< NHFONT_SIZE_MIN
1180 || iflags
.wc_fontsiz_menu
> NHFONT_SIZE_MAX
)
1181 iflags
.wc_fontsiz_menu
= NHFONT_DEFAULT_SIZE
;
1182 mar_set_font(NHW_MENU
, iflags
.wc_font_menu
, iflags
.wc_fontsiz_menu
);
1185 if (stricmp(pref
, "font_text") == 0
1186 || stricmp(pref
, "font_size_text") == 0) {
1187 if (iflags
.wc_fontsiz_text
< NHFONT_SIZE_MIN
1188 || iflags
.wc_fontsiz_text
> NHFONT_SIZE_MAX
)
1189 iflags
.wc_fontsiz_text
= NHFONT_DEFAULT_SIZE
;
1190 mar_set_font(NHW_TEXT
, iflags
.wc_font_text
, iflags
.wc_fontsiz_text
);
1193 if (stricmp(pref
, "scroll_margin") == 0) {
1194 mar_set_margin(iflags
.wc_scroll_margin
);
1195 Gem_cliparound(u
.ux
, u
.uy
);
1198 if (stricmp(pref
, "ascii_map") == 0) {
1199 mar_set_tile_mode(!iflags
.wc_ascii_map
);
1203 if (stricmp(pref
, "hilite_pet") == 0) {
1204 /* MAR -- works without doing something here. */
1207 if (stricmp(pref
, "align_message") == 0) {
1208 mar_set_msg_align(iflags
.wc_align_message
- ALIGN_BOTTOM
);
1211 if (stricmp(pref
, "align_status") == 0) {
1212 mar_set_status_align(iflags
.wc_align_status
- ALIGN_BOTTOM
);
1215 if (stricmp(pref
, "vary_msgcount") == 0) {
1216 mar_set_msg_visible(iflags
.wc_vary_msgcount
);
1221 * Allocate a copy of the given string. If null, return a string of
1224 * This is an exact duplicate of copy_of() in X11/winmenu.c.
1232 return strcpy((char *) alloc((unsigned) (strlen(s
) + 1)), s
);
1235 #endif /* GEM_GRAPHICS \