1 /* NetHack 3.6 windows.c $NHDT-Date: 1495232365 2017/05/19 22:19:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.41 $ */
2 /* Copyright (c) D. Cohrs, 1993. */
3 /* NetHack may be freely redistributed. See license for details. */
10 /* Cannot just blindly include winX.h without including all of X11 stuff
11 and must get the order of include files right. Don't bother. */
12 extern struct window_procs X11_procs;
13 extern void FDECL(win_X11_init, (int));
16 extern struct window_procs Qt_procs;
22 extern struct window_procs mac_procs;
25 extern struct window_procs beos_procs;
26 extern void FDECL(be_win_init, (int));
27 FAIL /* be_win_init doesn't exist? XXX*/
29 #ifdef AMIGA_INTUITION
30 extern struct window_procs amii_procs;
31 extern struct window_procs amiv_procs;
32 extern void FDECL(ami_wininit_data, (int));
35 extern struct window_procs win32_procs;
39 extern struct window_procs Gnome_procs;
42 extern struct window_procs mswin_procs;
45 extern struct window_procs chainin_procs;
46 extern void FDECL(chainin_procs_init, (int));
47 extern void *FDECL(chainin_procs_chain, (int, int, void *, void *, void *));
49 extern struct chain_procs chainout_procs;
50 extern void FDECL(chainout_procs_init, (int));
51 extern void *FDECL(chainout_procs_chain, (int, int, void *, void *, void *));
53 extern struct chain_procs trace_procs;
54 extern void FDECL(trace_procs_init, (int));
55 extern void *FDECL(trace_procs_chain, (int, int, void *, void *, void *));
58 STATIC_DCL void FDECL(def_raw_print, (const char *s));
61 STATIC_DCL winid FDECL(dump_create_nhwindow, (int));
62 STATIC_DCL void FDECL(dump_clear_nhwindow, (winid));
63 STATIC_DCL void FDECL(dump_display_nhwindow, (winid, BOOLEAN_P));
64 STATIC_DCL void FDECL(dump_destroy_nhwindow, (winid));
65 STATIC_DCL void FDECL(dump_start_menu, (winid));
66 STATIC_DCL void FDECL(dump_add_menu, (winid, int, const ANY_P *, CHAR_P, CHAR_P, int, const char *, BOOLEAN_P));
67 STATIC_DCL void FDECL(dump_end_menu, (winid, const char *));
68 STATIC_DCL int FDECL(dump_select_menu, (winid, int, MENU_ITEM_P **));
69 STATIC_DCL void FDECL(dump_putstr, (winid, int, const char *));
75 NEARDATA struct window_procs windowprocs;
83 static struct win_choices {
84 struct window_procs *procs;
85 void FDECL((*ini_routine), (int)); /* optional (can be 0) */
87 void *FDECL((*chain_routine), (int, int, void *, void *, void *));
91 { &tty_procs, win_tty_init CHAINR(0) },
94 { &X11_procs, win_X11_init CHAINR(0) },
97 { &Qt_procs, 0 CHAINR(0) },
100 { &Gem_procs, win_Gem_init CHAINR(0) },
103 { &mac_procs, 0 CHAINR(0) },
106 { &beos_procs, be_win_init CHAINR(0) },
108 #ifdef AMIGA_INTUITION
110 ami_wininit_data CHAINR(0) }, /* Old font version of the game */
112 ami_wininit_data CHAINR(0) }, /* Tile version of the game */
114 #ifdef WIN32_GRAPHICS
115 { &win32_procs, 0 CHAINR(0) },
117 #ifdef GNOME_GRAPHICS
118 { &Gnome_procs, 0 CHAINR(0) },
120 #ifdef MSWIN_GRAPHICS
121 { &mswin_procs, 0 CHAINR(0) },
124 { &chainin_procs, chainin_procs_init, chainin_procs_chain },
125 { (struct window_procs *) &chainout_procs, chainout_procs_init,
126 chainout_procs_chain },
128 { (struct window_procs *) &trace_procs, trace_procs_init,
131 { 0, 0 CHAINR(0) } /* must be last */
136 struct winlink *nextlink;
137 struct win_choices *wincp;
140 /* NB: this chain does not contain the terminal real window system pointer */
142 static struct winlink *chain = 0;
144 static struct winlink *
147 return calloc(1, sizeof(struct winlink));
150 wl_addhead(struct winlink *wl)
152 wl->nextlink = chain;
156 wl_addtail(struct winlink *wl)
158 struct winlink *p = chain;
164 while (p->nextlink) {
170 #endif /* WINCHAIN */
172 static struct win_choices *last_winchoice = 0;
175 genl_can_suspend_no(VOID_ARGS)
181 genl_can_suspend_yes(VOID_ARGS)
195 static struct win_choices *
201 for (i = 0; winchoices[i].procs; i++) {
202 if (!strcmpi(s, winchoices[i].procs->name)) {
203 return &winchoices[i];
206 return (struct win_choices *) 0;
216 for (i = 0; winchoices[i].procs; i++) {
217 if ('+' == winchoices[i].procs->name[0])
219 if ('-' == winchoices[i].procs->name[0])
221 if (!strcmpi(s, winchoices[i].procs->name)) {
222 windowprocs = *winchoices[i].procs;
224 if (last_winchoice && last_winchoice->ini_routine)
225 (*last_winchoice->ini_routine)(WININIT_UNDO);
226 if (winchoices[i].ini_routine)
227 (*winchoices[i].ini_routine)(WININIT);
228 last_winchoice = &winchoices[i];
233 if (!windowprocs.win_raw_print)
234 windowprocs.win_raw_print = def_raw_print;
236 if (!winchoices[0].procs) {
237 raw_printf("No window types?");
240 if (!winchoices[1].procs) {
241 config_error_add("Window type %s not recognized. The only choice is: %s",
242 s, winchoices[0].procs->name);
245 boolean first = TRUE;
247 for (i = 0; winchoices[i].procs; i++) {
248 if ('+' == winchoices[i].procs->name[0])
250 if ('-' == winchoices[i].procs->name[0])
252 Sprintf(eos(buf), "%s%s", first ? "" : ",", winchoices[i].procs->name);
255 config_error_add("Window type %s not recognized. Choices are: %s", s, buf);
258 if (windowprocs.win_raw_print == def_raw_print)
259 nh_terminate(EXIT_SUCCESS);
269 for (i = 0; winchoices[i].procs; i++) {
270 if ('+' != winchoices[i].procs->name[0])
272 if (!strcmpi(s, winchoices[i].procs->name)) {
273 struct winlink *p = wl_new();
274 p->wincp = &winchoices[i];
276 /* NB: The ini_routine() will be called during commit. */
281 windowprocs.win_raw_print = def_raw_print;
283 raw_printf("Window processor %s not recognized. Choices are:", s);
284 for (i = 0; winchoices[i].procs; i++) {
285 if ('+' != winchoices[i].procs->name[0])
287 raw_printf(" %s", winchoices[i].procs->name);
303 /* Save wincap* from the real window system - we'll restore it below. */
304 wincap = windowprocs.wincap;
305 wincap2 = windowprocs.wincap2;
307 /* add -chainin at head and -chainout at tail */
309 p->wincp = win_choices_find("-chainin");
311 raw_printf("Can't locate processor '-chainin'");
317 p->wincp = win_choices_find("-chainout");
319 raw_printf("Can't locate processor '-chainout'");
324 /* Now alloc() init() similar to Objective-C. */
325 for (n = 1, p = chain; p; n++, p = p->nextlink) {
326 p->linkdata = (*p->wincp->chain_routine)(WINCHAIN_ALLOC, n, 0, 0, 0);
329 for (n = 1, p = chain; p; n++, p = p->nextlink) {
331 (void) (*p->wincp->chain_routine)(WINCHAIN_INIT, n, p->linkdata,
332 p->nextlink->wincp->procs,
333 p->nextlink->linkdata);
335 (void) (*p->wincp->chain_routine)(WINCHAIN_INIT, n, p->linkdata,
336 last_winchoice->procs, 0);
340 /* Restore the saved wincap* values. We do it here to give the
341 * ini_routine()s a chance to change or check them. */
342 chain->wincp->procs->wincap = wincap;
343 chain->wincp->procs->wincap2 = wincap2;
345 /* Call the init procs. Do not re-init the terminal real win. */
347 while (p->nextlink) {
348 if (p->wincp->ini_routine) {
349 (*p->wincp->ini_routine)(WININIT);
354 /* Install the chain into window procs very late so ini_routine()s
355 * can raw_print on error. */
356 windowprocs = *chain->wincp->procs;
360 struct winlink *np = p->nextlink;
362 p = np; /* assignment, not proof */
365 #endif /* WINCHAIN */
368 * tty_message_menu() provides a means to get feedback from the
369 * --More-- prompt; other interfaces generally don't need that.
373 genl_message_menu(let, how, mesg)
384 genl_preference_update(pref)
385 const char *pref UNUSED;
387 /* window ports are expected to provide
388 their own preference update routine
389 for the preference capabilities that
391 Just return in this genl one. */
396 genl_getmsghistory(init)
399 /* window ports can provide
400 their own getmsghistory() routine to
401 preserve message history between games.
402 The routine is called repeatedly from
403 the core save routine, and the window
404 port is expected to successively return
405 each message that it wants saved, starting
406 with the oldest message first, finishing
407 with the most recent.
408 Return null pointer when finished.
414 genl_putmsghistory(msg, is_restoring)
416 boolean is_restoring;
418 /* window ports can provide
419 their own putmsghistory() routine to
420 load message history from a saved game.
421 The routine is called repeatedly from
422 the core restore routine, starting with
423 the oldest saved message first, and
424 finishing with the latest.
425 The window port routine is expected to
426 load the message recall buffers in such
427 a way that the ordering is preserved.
428 The window port routine should make no
429 assumptions about how many messages are
430 forthcoming, nor should it assume that
431 another message will follow this one,
432 so it should keep all pointers/indexes
433 intact at the end of each call.
436 /* this doesn't provide for reloading the message window with the
437 previous session's messages upon restore, but it does put the quest
438 message summary lines there by treating them as ordinary messages */
444 #ifdef HANGUPHANDLING
446 * Dummy windowing scheme used to replace current one with no-ops
447 * in order to avoid all terminal I/O after hangup/disconnect.
450 static int NDECL(hup_nhgetch);
451 static char FDECL(hup_yn_function, (const char *, const char *, CHAR_P));
452 static int FDECL(hup_nh_poskey, (int *, int *, int *));
453 static void FDECL(hup_getlin, (const char *, char *));
454 static void FDECL(hup_init_nhwindows, (int *, char **));
455 static void FDECL(hup_exit_nhwindows, (const char *));
456 static winid FDECL(hup_create_nhwindow, (int));
457 static int FDECL(hup_select_menu, (winid, int, MENU_ITEM_P **));
458 static void FDECL(hup_add_menu, (winid, int, const anything *, CHAR_P, CHAR_P,
459 int, const char *, BOOLEAN_P));
460 static void FDECL(hup_end_menu, (winid, const char *));
461 static void FDECL(hup_putstr, (winid, int, const char *));
462 static void FDECL(hup_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int));
463 static void FDECL(hup_outrip, (winid, int, time_t));
464 static void FDECL(hup_curs, (winid, int, int));
465 static void FDECL(hup_display_nhwindow, (winid, BOOLEAN_P));
466 static void FDECL(hup_display_file, (const char *, BOOLEAN_P));
468 static void FDECL(hup_cliparound, (int, int));
471 static void FDECL(hup_change_color, (int, long, int));
473 static short FDECL(hup_set_font_name, (winid, char *));
475 static char *NDECL(hup_get_color_string);
476 #endif /* CHANGE_COLOR */
477 static void FDECL(hup_status_update, (int, genericptr_t, int, int, int, unsigned long *));
479 static int NDECL(hup_int_ndecl);
480 static void NDECL(hup_void_ndecl);
481 static void FDECL(hup_void_fdecl_int, (int));
482 static void FDECL(hup_void_fdecl_winid, (winid));
483 static void FDECL(hup_void_fdecl_constchar_p, (const char *));
485 static struct window_procs hup_procs = {
486 "hup", 0L, 0L, hup_init_nhwindows,
487 hup_void_ndecl, /* player_selection */
488 hup_void_ndecl, /* askname */
489 hup_void_ndecl, /* get_nh_event */
490 hup_exit_nhwindows, hup_void_fdecl_constchar_p, /* suspend_nhwindows */
491 hup_void_ndecl, /* resume_nhwindows */
492 hup_create_nhwindow, hup_void_fdecl_winid, /* clear_nhwindow */
493 hup_display_nhwindow, hup_void_fdecl_winid, /* destroy_nhwindow */
494 hup_curs, hup_putstr, hup_putstr, /* putmixed */
495 hup_display_file, hup_void_fdecl_winid, /* start_menu */
496 hup_add_menu, hup_end_menu, hup_select_menu, genl_message_menu,
497 hup_void_ndecl, /* update_inventory */
498 hup_void_ndecl, /* mark_synch */
499 hup_void_ndecl, /* wait_synch */
504 (void FDECL((*), (char *))) hup_void_fdecl_constchar_p,
505 /* update_positionbar */
508 hup_void_fdecl_constchar_p, /* raw_print */
509 hup_void_fdecl_constchar_p, /* raw_print_bold */
510 hup_nhgetch, hup_nh_poskey, hup_void_ndecl, /* nhbell */
511 hup_int_ndecl, /* doprev_message */
512 hup_yn_function, hup_getlin, hup_int_ndecl, /* get_ext_cmd */
513 hup_void_fdecl_int, /* number_pad */
514 hup_void_ndecl, /* delay_output */
518 hup_void_fdecl_int, /* change_background */
521 hup_get_color_string,
522 #endif /* CHANGE_COLOR */
523 hup_void_ndecl, /* start_screen */
524 hup_void_ndecl, /* end_screen */
525 hup_outrip, genl_preference_update, genl_getmsghistory,
527 hup_void_ndecl, /* status_init */
528 hup_void_ndecl, /* status_finish */
529 genl_status_enablefield, hup_status_update,
533 static void FDECL((*previnterface_exit_nhwindows), (const char *)) = 0;
535 /* hangup has occurred; switch to no-op user interface */
539 char *FDECL((*previnterface_getmsghistory), (BOOLEAN_P)) = 0;
542 /* command processor shouldn't look for 2nd char after seeing ESC */
543 iflags.altmeta = FALSE;
546 /* don't call exit_nhwindows() directly here; if a hangup occurs
547 while interface code is executing, exit_nhwindows could knock
548 the interface's active data structures out from under itself */
549 if (iflags.window_inited
550 && windowprocs.win_exit_nhwindows != hup_exit_nhwindows)
551 previnterface_exit_nhwindows = windowprocs.win_exit_nhwindows;
553 /* also, we have to leave the old interface's getmsghistory()
554 in place because it will be called while saving the game */
555 if (windowprocs.win_getmsghistory != hup_procs.win_getmsghistory)
556 previnterface_getmsghistory = windowprocs.win_getmsghistory;
558 windowprocs = hup_procs;
560 if (previnterface_getmsghistory)
561 windowprocs.win_getmsghistory = previnterface_getmsghistory;
565 hup_exit_nhwindows(lastgasp)
566 const char *lastgasp;
568 /* core has called exit_nhwindows(); call the previous interface's
569 shutdown routine now; xxx_exit_nhwindows() needs to call other
570 xxx_ routines directly rather than through windowprocs pointers */
571 if (previnterface_exit_nhwindows) {
572 lastgasp = 0; /* don't want exit routine to attempt extra output */
573 (*previnterface_exit_nhwindows)(lastgasp);
574 previnterface_exit_nhwindows = 0;
576 iflags.window_inited = 0;
580 hup_nhgetch(VOID_ARGS)
582 return '\033'; /* ESC */
587 hup_yn_function(prompt, resp, deflt)
588 const char *prompt UNUSED, *resp UNUSED;
598 hup_nh_poskey(x, y, mod)
599 int *x UNUSED, *y UNUSED, *mod UNUSED;
606 hup_getlin(prompt, outbuf)
607 const char *prompt UNUSED;
610 Strcpy(outbuf, "\033");
615 hup_init_nhwindows(argc_p, argv)
619 iflags.window_inited = 1;
624 hup_create_nhwindow(type)
632 hup_select_menu(window, how, menu_list)
635 struct mi **menu_list UNUSED;
642 hup_add_menu(window, glyph, identifier, sel, grpsel, attr, txt, preselected)
644 int glyph UNUSED, attr UNUSED;
645 const anything *identifier UNUSED;
646 char sel UNUSED, grpsel UNUSED;
647 const char *txt UNUSED;
648 boolean preselected UNUSED;
655 hup_end_menu(window, prompt)
657 const char *prompt UNUSED;
664 hup_putstr(window, attr, text)
667 const char *text UNUSED;
674 hup_print_glyph(window, x, y, glyph, bkglyph)
676 xchar x UNUSED, y UNUSED;
685 hup_outrip(tmpwin, how, when)
695 hup_curs(window, x, y)
697 int x UNUSED, y UNUSED;
704 hup_display_nhwindow(window, blocking)
706 boolean blocking UNUSED;
713 hup_display_file(fname, complain)
714 const char *fname UNUSED;
715 boolean complain UNUSED;
724 int x UNUSED, y UNUSED;
733 hup_change_color(color, rgb, reverse)
743 hup_set_font_name(window, fontname)
752 hup_get_color_string(VOID_ARGS)
756 #endif /* CHANGE_COLOR */
760 hup_status_update(idx, ptr, chg, pc, color, colormasks)
762 genericptr_t ptr UNUSED;
763 int chg UNUSED, pc UNUSED, color UNUSED;
764 unsigned long *colormasks UNUSED;
771 * Non-specific stubs.
775 hup_int_ndecl(VOID_ARGS)
781 hup_void_ndecl(VOID_ARGS)
788 hup_void_fdecl_int(arg)
796 hup_void_fdecl_winid(window)
804 hup_void_fdecl_constchar_p(string)
805 const char *string UNUSED;
810 #endif /* HANGUPHANDLING */
813 /****************************************************************************/
814 /* genl backward compat stuff */
815 /****************************************************************************/
817 const char *status_fieldnm[MAXBLSTATS];
818 const char *status_fieldfmt[MAXBLSTATS];
819 char *status_vals[MAXBLSTATS];
820 boolean status_activefields[MAXBLSTATS];
821 NEARDATA winid WIN_STATUS;
828 for (i = 0; i < MAXBLSTATS; ++i) {
829 status_vals[i] = (char *) alloc(MAXCO);
830 *status_vals[i] = '\0';
831 status_activefields[i] = FALSE;
832 status_fieldfmt[i] = (const char *) 0;
834 /* Use a window for the genl version; backward port compatibility */
835 WIN_STATUS = create_nhwindow(NHW_STATUS);
836 display_nhwindow(WIN_STATUS, FALSE);
842 /* tear down routine */
845 /* free alloc'd memory here */
846 for (i = 0; i < MAXBLSTATS; ++i) {
848 free((genericptr_t) status_vals[i]), status_vals[i] = (char *) 0;
853 genl_status_enablefield(fieldidx, nm, fmt, enable)
859 status_fieldfmt[fieldidx] = fmt;
860 status_fieldnm[fieldidx] = nm;
861 status_activefields[fieldidx] = enable;
864 /* call once for each field, then call with BL_FLUSH to output the result */
866 genl_status_update(idx, ptr, chg, percent, color, colormasks)
869 int chg UNUSED, percent UNUSED, color UNUSED;
870 unsigned long *colormasks UNUSED;
872 char newbot1[MAXCO], newbot2[MAXCO];
873 long cond, *condptr = (long *) ptr;
875 unsigned pass, lndelta;
876 enum statusfields idx1, idx2, *fieldlist;
877 char *nb, *text = (char *) ptr;
879 static enum statusfields fieldorder[][15] = {
881 { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_ALIGN,
882 BL_SCORE, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH,
884 /* line two, default order */
885 { BL_LEVELDESC, BL_GOLD,
886 BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC,
887 BL_XP, BL_EXP, BL_HD,
889 BL_HUNGER, BL_CAP, BL_CONDITION,
891 /* move time to the end */
892 { BL_LEVELDESC, BL_GOLD,
893 BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC,
894 BL_XP, BL_EXP, BL_HD,
895 BL_HUNGER, BL_CAP, BL_CONDITION,
897 /* move experience and time to the end */
898 { BL_LEVELDESC, BL_GOLD,
899 BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC,
900 BL_HUNGER, BL_CAP, BL_CONDITION,
901 BL_XP, BL_EXP, BL_HD, BL_TIME, BL_FLUSH },
902 /* move level description plus gold and experience and time to end */
903 { BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC,
904 BL_HUNGER, BL_CAP, BL_CONDITION,
905 BL_LEVELDESC, BL_GOLD, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_FLUSH },
908 /* in case interface is using genl_status_update() but has not
909 specified WC2_FLUSH_STATUS (status_update() for field values
910 is buffered so final BL_FLUSH is needed to produce output) */
911 windowprocs.wincap2 |= WC2_FLUSH_STATUS;
913 if (idx != BL_FLUSH) {
914 if (!status_activefields[idx])
918 cond = condptr ? *condptr : 0L;
919 nb = status_vals[idx];
921 if (cond & BL_MASK_STONE)
922 Strcpy(nb = eos(nb), " Stone");
923 if (cond & BL_MASK_SLIME)
924 Strcpy(nb = eos(nb), " Slime");
925 if (cond & BL_MASK_STRNGL)
926 Strcpy(nb = eos(nb), " Strngl");
927 if (cond & BL_MASK_FOODPOIS)
928 Strcpy(nb = eos(nb), " FoodPois");
929 if (cond & BL_MASK_TERMILL)
930 Strcpy(nb = eos(nb), " TermIll");
931 if (cond & BL_MASK_BLIND)
932 Strcpy(nb = eos(nb), " Blind");
933 if (cond & BL_MASK_DEAF)
934 Strcpy(nb = eos(nb), " Deaf");
935 if (cond & BL_MASK_STUN)
936 Strcpy(nb = eos(nb), " Stun");
937 if (cond & BL_MASK_CONF)
938 Strcpy(nb = eos(nb), " Conf");
939 if (cond & BL_MASK_HALLU)
940 Strcpy(nb = eos(nb), " Hallu");
941 if (cond & BL_MASK_LEV)
942 Strcpy(nb = eos(nb), " Lev");
943 if (cond & BL_MASK_FLY)
944 Strcpy(nb = eos(nb), " Fly");
945 if (cond & BL_MASK_RIDE)
946 Strcpy(nb = eos(nb), " Ride");
949 Sprintf(status_vals[idx],
950 status_fieldfmt[idx] ? status_fieldfmt[idx] : "%s",
954 return; /* processed one field other than BL_FLUSH */
955 } /* (idx != BL_FLUSH) */
957 /* We've received BL_FLUSH; time to output the gathered data */
960 for (i = 0; (idx1 = fieldorder[0][i]) != BL_FLUSH; ++i) {
961 if (status_activefields[idx1])
962 Strcpy(nb = eos(nb), status_vals[idx1]);
964 /* if '$' is encoded, buffer length of \GXXXXNNNN is 9 greater than
965 single char; we want to subtract that 9 when checking display length */
966 lndelta = (status_activefields[BL_GOLD]
967 && strstr(status_vals[BL_GOLD], "\\G")) ? 9 : 0;
968 /* basic bot2 formats groups of second line fields into five buffers,
969 then decides how to order those buffers based on comparing lengths
970 of [sub]sets of them to the width of the map; we have more control
971 here but currently emulate that behavior */
972 for (pass = 1; pass <= 4; pass++) {
973 fieldlist = fieldorder[pass];
976 for (i = 0; (idx2 = fieldlist[i]) != BL_FLUSH; ++i) {
977 if (status_activefields[idx2]) {
978 const char *val = status_vals[idx2];
981 case BL_HP: /* for pass 4, Hp comes first; mungspaces()
982 will strip the unwanted leading spaces */
983 case BL_XP: case BL_HD:
985 Strcpy(nb = eos(nb), " ");
988 /* leveldesc has no leading space, so if we've moved
989 it past the first position, provide one */
991 Strcpy(nb = eos(nb), " ");
994 * We want " hunger encumbrance conditions"
995 * or " encumbrance conditions"
996 * or " hunger conditions"
998 * 'hunger' is either " " or " hunger_text";
999 * 'encumbrance' is either " " or " encumbrance_text";
1000 * 'conditions' is either "" or " cond1 cond2...".
1003 /* hunger==" " - keep it, end up with " ";
1004 hunger!=" " - insert space and get " hunger" */
1005 if (strcmp(val, " "))
1006 Strcpy(nb = eos(nb), " ");
1009 /* cap==" " - suppress it, retain " hunger" or " ";
1010 cap!=" " - use it, get " hunger cap" or " cap" */
1011 if (!strcmp(val, " "))
1017 Strcpy(nb = eos(nb), val); /* status_vals[idx2] */
1018 } /* status_activefields[idx2] */
1020 if (idx2 == BL_CONDITION && pass < 4
1021 && strlen(newbot2) - lndelta > COLNO)
1022 break; /* switch to next order */
1025 if (idx2 == BL_FLUSH) { /* made it past BL_CONDITION */
1027 mungspaces(newbot2);
1031 curs(WIN_STATUS, 1, 0);
1032 putstr(WIN_STATUS, 0, newbot1);
1033 curs(WIN_STATUS, 1, 1);
1034 putmixed(WIN_STATUS, 0, newbot2); /* putmixed() due to GOLD glyph */
1037 STATIC_VAR struct window_procs dumplog_windowprocs_backup;
1038 STATIC_VAR FILE *dumplog_file;
1041 STATIC_VAR time_t dumplog_now;
1043 STATIC_DCL char *FDECL(dump_fmtstr, (const char *, char *));
1046 dump_fmtstr(fmt, buf)
1050 const char *fp = fmt;
1059 uid = (long) getuid();
1062 * Note: %t and %T assume that time_t is a 'long int' number of
1063 * seconds since some epoch value. That's quite iffy.... The
1064 * unit of time might be different and the datum size might be
1065 * some variant of 'long long int'. [Their main purpose is to
1066 * construct a unique file name rather than record the date and
1067 * time; violating the 'long seconds since base-date' assumption
1068 * may or may not interfere with that usage.]
1071 while (fp && *fp && len < BUFSZ-1) {
1077 case '\0': /* fallthrough */
1078 case '%': /* literal % */
1079 Sprintf(tmpbuf, "%%");
1081 case 't': /* game start, timestamp */
1082 Sprintf(tmpbuf, "%lu", (unsigned long) ubirthday);
1084 case 'T': /* current time, timestamp */
1085 Sprintf(tmpbuf, "%lu", (unsigned long) now);
1087 case 'd': /* game start, YYYYMMDDhhmmss */
1088 Sprintf(tmpbuf, "%08ld%06ld",
1089 yyyymmdd(ubirthday), hhmmss(ubirthday));
1091 case 'D': /* current time, YYYYMMDDhhmmss */
1092 Sprintf(tmpbuf, "%08ld%06ld", yyyymmdd(now), hhmmss(now));
1094 case 'v': /* version, eg. "3.6.1-0" */
1095 Sprintf(tmpbuf, "%s", version_string(verbuf));
1098 Sprintf(tmpbuf, "%ld", uid);
1100 case 'n': /* player name */
1101 Sprintf(tmpbuf, "%s", *plname ? plname : "unknown");
1103 case 'N': /* first character of player name */
1104 Sprintf(tmpbuf, "%c", *plname ? *plname : 'u');
1108 slen = strlen(tmpbuf);
1109 if (len + slen < BUFSZ-1) {
1111 Sprintf(bp, "%s", tmpbuf);
1127 #endif /* DUMPLOG */
1139 if (!sysopt.dumplogfile)
1141 fname = dump_fmtstr(sysopt.dumplogfile, buf);
1143 fname = dump_fmtstr(DUMPLOG_FILE, buf);
1145 dumplog_file = fopen(fname, "w");
1146 dumplog_windowprocs_backup = windowprocs;
1157 (void) fclose(dumplog_file);
1158 dumplog_file = (FILE *) 0;
1163 dump_forward_putstr(win, attr, str, no_forward)
1170 fprintf(dumplog_file, "%s\n", str);
1172 putstr(win, attr, str);
1177 dump_putstr(win, attr, str)
1183 fprintf(dumplog_file, "%s\n", str);
1187 dump_create_nhwindow(dummy)
1195 dump_clear_nhwindow(win)
1203 dump_display_nhwindow(win, p)
1212 dump_destroy_nhwindow(win)
1220 dump_start_menu(win)
1228 dump_add_menu(win, glyph, identifier, ch, gch, attr, str, preselected)
1231 const anything *identifier UNUSED;
1236 boolean preselected UNUSED;
1239 if (glyph == NO_GLYPH)
1240 fprintf(dumplog_file, " %s\n", str);
1242 fprintf(dumplog_file, " %c - %s\n", ch, str);
1248 dump_end_menu(win, str)
1254 fprintf(dumplog_file, "%s\n", str);
1256 fputs("\n", dumplog_file);
1261 dump_select_menu(win, how, item)
1266 *item = (menu_item *) 0;
1271 dump_redirect(onoff_flag)
1276 windowprocs.win_create_nhwindow = dump_create_nhwindow;
1277 windowprocs.win_clear_nhwindow = dump_clear_nhwindow;
1278 windowprocs.win_display_nhwindow = dump_display_nhwindow;
1279 windowprocs.win_destroy_nhwindow = dump_destroy_nhwindow;
1280 windowprocs.win_start_menu = dump_start_menu;
1281 windowprocs.win_add_menu = dump_add_menu;
1282 windowprocs.win_end_menu = dump_end_menu;
1283 windowprocs.win_select_menu = dump_select_menu;
1284 windowprocs.win_putstr = dump_putstr;
1286 windowprocs = dumplog_windowprocs_backup;
1288 iflags.in_dumplog = onoff_flag;
1290 iflags.in_dumplog = FALSE;