]> granicus.if.org Git - nethack/commitdiff
status display - core modules (trunk only)
authornethack.allison <nethack.allison>
Sun, 23 Nov 2003 06:43:17 +0000 (06:43 +0000)
committernethack.allison <nethack.allison>
Sun, 23 Nov 2003 06:43:17 +0000 (06:43 +0000)
Introduction of a new set of window port status display
routines.  The new routines are conditional on
STATUS_VIA_WINDOWPORT
being defined in config.h. See the experimental section,
where the #define resides for the time being.

12 files changed:
doc/window.doc
include/config.h
include/decl.h
include/extern.h
include/winprocs.h
include/wintype.h
src/allmain.c
src/botl.c
src/decl.c
src/end.c
src/options.c
src/save.c

index 126c58e2ca1fa1a8be7c3777b9f5aae9a33eaa09..871f3ef403a12f9423a16af71268ec9eb97c5ca9 100644 (file)
@@ -20,16 +20,19 @@ Contents:
 
 I.  Window Types and Terminology
 
-There are 5 basic window types, used to call create_nhwindow():
+There are 4 basic window types, used to call create_nhwindow():
 
        NHW_MESSAGE     (top line)
-       NHW_STATUS      (bottom lines)
        NHW_MAP         (main dungeon)
        NHW_MENU        (inventory or other "corner" windows)
        NHW_TEXT        (help/text, full screen paged window)
 
 The tty window-port also uses NHW_BASE (the base display) internally.
 
+(The genl_status_* routines use NHW_STATUS for backward compatibility
+ when displaying status information on the bottom lines.  New code
+ should not use NHW_STATUS. NHW_STATUS will be phased out over time.)
+
 NHW_MENU windows can be used for either menu or text display.  Their
 basic feature is that for the tty-port, if the window is small enough,
 it appears in the corner of the tty display instead of overwriting
@@ -53,12 +56,16 @@ integer, but doesn't necessarily have to be done that way.  There are
 a few fixed window names that are known throughout the code:
 
        WIN_MESSAGE     (top line)
-       WIN_STATUS      (bottom lines)
        WIN_MAP         (main dungeon)
        WIN_INVEN       (inventory)
 
 Other windows are created and destroyed as needed.
 
+(The genl_status_* routines use WIN_STATUS for backward compatibility
+ when displaying status information on the bottom lines.  New code
+ should not use WIN_STATUS, or assume its presence. NHW_STATUS will 
+ be phased out over time.)
+
 "Port" in this document refers to a CPU/OS/hardware platform (UNIX, MSDOS
 TOS, etc.)  "window-port" refers to the windowing platform.  This is
 orthogonal (e.g.  UNIX might use either a tty window-port or an X11
@@ -85,12 +92,12 @@ curs(window, x, y)
                   displayable cursor to (x,y).  For backward compatibility,
                   1 <= x < cols, 0 <= y < rows, where cols and rows are
                   the size of window.
-               -- For variable sized windows, like the status window, the
+               -- For variable sized windows, like the old status window, the
                   behavior when curs() is called outside the window's limits
                   is unspecified. The mac port wraps to 0, with the status
                   window being 2 lines high and 80 columns wide.
-               -- Still used by curs_on_u(), status updates, screen locating
-                  (identify, teleport).
+               -- Still used by curs_on_u(), obsolete status updates, 
+                  screen locating (identify, teleport).
                -- NHW_MESSAGE, NHW_MENU and NHW_TEXT windows do not
                   currently support curs in the tty window-port.
 putstr(window, attr, str)
@@ -331,7 +338,51 @@ char message_menu(char let, int how, const char *mesg)
                   windows typically won't need this functionality, so can
                   substitute genl_message_menu (windows.c) instead.
 
-D.  Misc. Routines
+D.  Status Display Routines
+
+status_init()   -- core calls this to notify the window port that a status
+                  display is required. The window port should perform 
+                  the necessary initialization in here, allocate memory, etc.
+status_enablefield(int fldindex, char fldname, char fieldfmt, boolean enable)   
+                -- notifies the window port which fields it is authorized to
+                  display.
+               -- This may be called at any time, and is used
+                  to disable as well as enable fields, depending on the 
+                  value of the final argument (TRUE = enable).
+               -- fldindex could be one of the following from botl.h:
+                  BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, 
+                  BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, 
+                  BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX, 
+                  BL_LEVELDESC, BL_EXP, BL_CONDITION
+               -- There are MAXBLSTATS status fields (from botl.h)
+status_update(int fldindex, genericptr_t ptr, int chg, int percentage)
+               -- update the value of a status field
+               -- the fldindex identifies which field is changing and
+                  is an integer index value from botl.h
+               -- fldindex could be any one of the following from botl.h:
+                  BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, 
+                  BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, 
+                  BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX, 
+                  BL_LEVELDESC, BL_EXP, BL_CONDITION, 
+               -- fldindex could also be BL_FLUSH (-1), which is not really
+                  a field index, but is a special trigger to tell the 
+                  windowport that it should redisplay all its status fields,
+                  even if no changes have been presented to it.
+               -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
+                  If fldindex is BL_CONDITION, then ptr is a long value with
+                  any or none of the following bits set (from botl.h):
+                       BL_MASK_BLIND           0x00000001L
+                       BL_MASK_CONF            0x00000002L
+                       BL_MASK_FOODPOIS        0x00000004L
+                       BL_MASK_ILL             0x00000008L
+                       BL_MASK_HALLU           0x00000010L
+                       BL_MASK_STUNNED         0x00000020L
+                       BL_MASK_SLIMED          0x00000040L
+status_finish() -- called when it is time for the window port to tear down
+                  the status display and free allocated memory, etc.
+
+
+E.  Misc. Routines
 
 make_sound(???) -- To be determined later.  THIS IS CURRENTLY UN-IMPLEMENTED.
 nhbell()       -- Beep at user.  [This will exist at least until sounds are
@@ -414,8 +465,11 @@ the window interface to the rest of NetHack.
 
 char toplines[BUFSZ]   Contains the last message printed to the WIN_MESSAGE
                        window, used by Norep().
-winid WIN_MESSAGE, WIN_MAP, WIN_STATUS, WIN_INVEN
-                       The four standard windows.
+winid WIN_MESSAGE, WIN_MAP, WIN_INVEN
+                       The three standard windows.
+                       There is also a window called WIN_STATUS that is used
+                       only for backward compatibility in the genl_status_*
+                       set of generic status display functions.
 char *AE, *AS;         Checked in options.c to see if we should switch
                        to DEC_GRAPHICS.  It is #ifdefed VMS and UNIX.
 int LI, CO;            Set in sys/unix/ioctl.c.
@@ -560,7 +614,7 @@ to support:
   +--------------------+--------------------+--------------------+--------+
 
 align_message  -- where to place message window (top, bottom, left, right)
-align_status   -- where to place status window (top, bottom, left, right).
+align_status   -- where to place status display (top, bottom, left, right).
 ascii_map      -- port should display an ascii map if it can.
 color          -- port should display color if it can.
 eight_bit_tty  -- port should allow eight bit input.
@@ -571,9 +625,9 @@ font_size_map       -- port should use this size font for the map window.
 font_size_menu -- port should use this size font for menu windows.
 font_size_message 
                -- port should use this size font for the message window.
-font_size_status-- port should use this size font for the status window.
+font_size_status-- port should use this size font for the status display.
 font_size_text -- port should use this size font for text windows.
-font_status    -- port should use a font by this name for status window.
+font_status    -- port should use a font by this name for status display.
 font_text      -- port should use a font by this name for text windows.
 fullscreen      -- port should try to use the whole screen.
 hilite_pet     -- port should mark pets in some special way on the map.
@@ -718,9 +772,9 @@ to initialize the function pointer table to _something_ so that calls to
 raw_print() will not fail.  Choose_windows() should be called almost
 immediately upon entering main().  Look at unixmain.c for an example.
 
-Display_gamewindows() is a common routine that displays the three standard
-game windows (WIN_MESSAGE, WIN_MAP, and WIN_STATUS).  It is normally called
-just before the "Hello, welcome" message.
+Display_gamewindows() is a common routine that displays the two standard
+game windows (WIN_MESSAGE, WIN_MAP), and the status display.  It is normally 
+called just before the "Hello, welcome" message.
 
 Process_options() is currently still unique to each port.  There may be need
 in the future to make it possible to replace this on a per window-port basis.
index ab0a154557ccb9f54aca61898eb3219b24a275d9..5873a2a40f30c69a04fb7f201b5986a4220021b4 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)config.h   3.4     2003/02/19      */
+/*     SCCS Id: @(#)config.h   3.4     2003/11/23      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -353,7 +353,8 @@ typedef unsigned char       uchar;
  */
 
 /*#define GOLDOBJ */   /* Gold is kept on obj chains - Helge Hafting */
-#define AUTOPICKUP_EXCEPTIONS  /* exceptions to autopickup - M. Allison */
+#define AUTOPICKUP_EXCEPTIONS  /* exceptions to autopickup */
+#define STATUS_VIA_WINDOWPORT  /* re-work of the status line updating process */
 
 /* End of Section 5 */
 
index 12452c731ef9c65cd562847b81ece9d8842929ad..734e8ec025897c956f67b86c32d9598f86b37a1e 100644 (file)
@@ -320,7 +320,10 @@ E NEARDATA boolean vision_full_recalc;     /* TRUE if need vision recalc */
 E NEARDATA char **viz_array;           /* could see/in sight row pointers */
 
 /* Window system stuff */
-E NEARDATA winid WIN_MESSAGE, WIN_STATUS;
+E NEARDATA winid WIN_MESSAGE;
+#ifndef STATUS_VIA_WINDOWPORT
+E NEARDATA winid WIN_STATUS;
+#endif
 E NEARDATA winid WIN_MAP, WIN_INVEN;
 E char toplines[];
 #ifndef TCAP_H
index 05f459f2a557ed79f82a1f036006bb230fb494fb..6a59bb7616dac2b769781d90ac5cd5ec030b2e01 100644 (file)
@@ -131,6 +131,14 @@ E long NDECL(botl_score);
 E int FDECL(describe_level, (char *));
 E const char *FDECL(rank_of, (int,SHORT_P,BOOLEAN_P));
 E void NDECL(bot);
+#ifdef STATUS_VIA_WINDOWPORT
+E void FDECL(status_initialize, (BOOLEAN_P));
+E void NDECL(status_finish);
+E void NDECL(genl_status_init);
+E void NDECL(genl_status_finish);
+E void FDECL(genl_status_update, (int, genericptr_t, int, int));
+E void FDECL(genl_status_enablefield, (int, const char *, const char *,BOOLEAN_P));
+#endif
 
 /* ### cmd.c ### */
 
index c1a7eca7992d4f436be09c7345214649d4fb1708..a9b9106c74bc97f6d4fce9b49f6a3e55d45d8eb2 100644 (file)
@@ -5,6 +5,8 @@
 #ifndef WINPROCS_H
 #define WINPROCS_H
 
+#include "botl.h"
+
 struct window_procs {
     const char *name;
     unsigned long wincap;      /* window port capability options supported */
@@ -67,6 +69,12 @@ struct window_procs {
     void FDECL((*win_preference_update), (const char *));
     char * FDECL((*win_getmsghistory), (BOOLEAN_P));
     void FDECL((*win_putmsghistory), (const char *));
+#ifdef STATUS_VIA_WINDOWPORT
+    void NDECL((*win_status_init));
+    void NDECL((*win_status_finish));
+    void FDECL((*win_status_enablefield), (int,const char *,const char *,BOOLEAN_P));
+    void FDECL((*win_status_update), (int,genericptr_t,int,int));
+#endif
 };
 
 extern NEARDATA struct window_procs windowprocs;
@@ -138,6 +146,13 @@ extern NEARDATA struct window_procs windowprocs;
 #define preference_update (*windowprocs.win_preference_update)
 #define getmsghistory (*windowprocs.win_getmsghistory)
 #define putmsghistory (*windowprocs.win_putmsghistory)
+#ifdef STATUS_VIA_WINDOWPORT
+/* there is a status_initialize() in botl.c,
+ * which calls win_status_init() directly; same with status_finish.
+ */
+#define status_enablefield (*windowprocs.win_status_enablefield)
+#define status_update (*windowprocs.win_status_update)
+#endif
 
 /*
  * WINCAP
index b7a4aa12bb08df41ab6e899352195d707923efab..c53371508ba8633e62d09970b6acb15638fe81cb 100644 (file)
@@ -14,6 +14,10 @@ typedef union any {
     int  a_int;
     char a_char;
     schar a_schar;
+    unsigned int a_uint;
+    int *a_iptr;
+    long *a_lptr;
+    unsigned *a_uptr;
     /* add types as needed */
 } anything;
 #define ANY_P union any /* avoid typedef in prototypes */
@@ -67,5 +71,4 @@ typedef struct mi {
 #define MENU_INVERT_PAGE       '~'
 #define MENU_SEARCH            ':'
 
-
 #endif /* WINTYPE_H */
index 91ec6a2341b42112e358d6ecb9368dbd079a8163..9ea7220ef32383e4cb760d9018695ec164244406 100644 (file)
@@ -447,7 +447,11 @@ void
 display_gamewindows()
 {
     WIN_MESSAGE = create_nhwindow(NHW_MESSAGE);
+#ifdef STATUS_VIA_WINDOWPORT
+    status_initialize(FALSE);
+#else
     WIN_STATUS = create_nhwindow(NHW_STATUS);
+#endif
     WIN_MAP = create_nhwindow(NHW_MAP);
     WIN_INVEN = create_nhwindow(NHW_MENU);
 
@@ -466,7 +470,9 @@ display_gamewindows()
      * The mac port is not DEPENDENT on the order of these
      * displays, but it looks a lot better this way...
      */
+#ifndef STATUS_VIA_WINDOWPORT
     display_nhwindow(WIN_STATUS, FALSE);
+#endif
     display_nhwindow(WIN_MESSAGE, FALSE);
     clear_glyph_buffer();
     display_nhwindow(WIN_MAP, FALSE);
index e838ba2968e97f32fb146a060d28cbba29e24b1d..b20180de43ab2bd7eb1f090640a83136fc80bfd7 100644 (file)
@@ -15,8 +15,12 @@ const char * const enc_stat[] = {
        "Overloaded"
 };
 
+#ifdef STATUS_VIA_WINDOWPORT
+STATIC_OVL void NDECL(init_blstats);
+#else
 STATIC_DCL void NDECL(bot1);
 STATIC_DCL void NDECL(bot2);
+#endif
 
 /* MAXCO must hold longest uncompressed status line, and must be larger
  * than COLNO
@@ -150,13 +154,13 @@ botl_score()
 }
 #endif
 
+#ifndef STATUS_VIA_WINDOWPORT
 STATIC_OVL void
 bot1()
 {
        char newbot1[MAXCO];
        register char *nb;
        register int i,j;
-
        Strcpy(newbot1, plname);
        if('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A'-'a';
        newbot1[10] = 0;
@@ -203,6 +207,7 @@ bot1()
        curs(WIN_STATUS, 1, 0);
        putstr(WIN_STATUS, 0, newbot1);
 }
+#endif
 
 /* provide the name of the current level for display by various ports */
 int
@@ -227,6 +232,7 @@ char *buf;
        return ret;
 }
 
+#ifndef STATUS_VIA_WINDOWPORT
 STATIC_OVL void
 bot2()
 {
@@ -289,4 +295,530 @@ bot()
        context.botl = context.botlx = 0;
 }
 
+#else  /* STATUS_VIA_WINDOWPORT */
+
+/* These are used within botl.c only */
+#define P_MASK 1
+#define P_STR  2
+#define P_INT  3
+#define P_LNG  4
+#define P_UINT 5
+
+struct istat_s {
+       long time;
+       unsigned ptype;
+       anything ptr;
+       char *val;
+       int valwidth;
+       int idxmax;
+};
+
+#define percentage(current, maximum)   ((100 * current) / maximum)
+#define percentagel(current, maximum)  ((int)((100L * current) / maximum))
+
+/* If entries are added to this, botl.h will required updating too */
+struct istat_s blstats[2][MAXBLSTATS] = {
+       {
+       { 0L, P_STR, (genericptr_t)0, (char *)0, 80, 0},        /*  0 BL_TITLE */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /*  1 BL_STR */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /*  2 BL_DX */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /*  3 BL_CO */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /*  4 BL_IN */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /*  5 BL_WI */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /*  6 BL_CH */
+       { 0L, P_STR, (genericptr_t)0, (char *)0, 8,  0},        /*  7 BL_ALIGN */
+       { 0L, P_LNG, (genericptr_t)0, (char *)0, 20, 0},        /*  8 BL_SCORE */
+       { 0L, P_LNG, (genericptr_t)0, (char *)0, 20, 0},        /*  9 BL_CAP */
+       { 0L, P_LNG, (genericptr_t)0, (char *)0, 8,  0},        /* 10 BL_GOLD */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6, BL_ENEMAX}, /* 11 BL_ENE */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /* 12 BL_ENEMAX */
+       { 0L, P_LNG, (genericptr_t)0, (char *)0, 6,  0},        /* 13 BL_XP */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /* 14 BL_AC */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 6,  0},        /* 15 BL_HD */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 10, 0},        /* 16 BL_TIME */
+       { 0L, P_UINT,(genericptr_t)0, (char *)0, 20, 0},        /* 17 BL_HUNGER */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 10,BL_HPMAX},  /* 18 BL_HP */
+       { 0L, P_INT, (genericptr_t)0, (char *)0, 10, 0},        /* 19 BL_HPMAX */
+       { 0L, P_STR, (genericptr_t)0, (char *)0, 80, 0},        /* 20 BL_LEVELDESC */
+       { 0L, P_LNG, (genericptr_t)0, (char *)0, 20, 0},        /* 21 BL_EXP */
+       { 0L, P_MASK,(genericptr_t)0, (char *)0, 0, 0}, /* 22 BL_CONDITION */
+       }
+};
+
+static boolean update_all = FALSE;
+
+void
+status_initialize(reassessment)
+boolean reassessment;  /* TRUE = just reassess fields w/o other initialization*/
+{
+       int i;
+       const char *fieldfmts[] = {
+               "%s"," St:%s"," Dx:%s"," Co:%s"," In:%s"," Wi:%s"," Ch:%s",
+               " %s"," S:%s"," %s"," %s"," Pw:%s", "(%s)"," Xp:%s", " AC:%s",
+               " HD:%s"," T:%s"," %s"," HP:%s","(%s)","%s","/%s","%s"
+               };
+       const char *fieldnames[] = {
+               "title", "strength", "dexterity", "constitution", "intelligence",
+               "wisdom", "charisma", "alignment", "score", "capacity",
+               "gold", "power", "power-max", "experience-level", "armor-class",
+               "HD", "time", "hunger", "hitpoints", "hitpoints-max",
+               "dungeon-level", "experience", "condition"
+               };
+       if (!reassessment) {
+               init_blstats();
+               (*windowprocs.win_status_init)();
+       }
+       for (i = 0; i < MAXBLSTATS; ++i) {
+               if ((i == BL_SCORE && !flags.showscore) ||
+                   (i == BL_EXP   && !flags.showexp) ||
+                   (i == BL_TIME  && !flags.time))
+                       status_enablefield(i, fieldnames[i], fieldfmts[i], FALSE);
+               else
+                       status_enablefield(i, fieldnames[i], fieldfmts[i], TRUE);
+       }
+       update_all = TRUE;
+}
+
+void
+status_finish()
+{
+       int i;
+
+       /* call the window port cleanup routine first */
+       (*windowprocs.win_status_finish)();
+
+       /* free memory that we alloc'd now */
+       for (i = 0; i < MAXBLSTATS; ++i) {
+               free(blstats[0][i].ptr.a_void);
+               free(blstats[1][i].ptr.a_void);
+               if (blstats[0][i].val) free((genericptr_t)blstats[0][i].val);
+               if (blstats[1][i].val) free((genericptr_t)blstats[1][i].val);
+       }
+}
+
+STATIC_OVL void
+init_blstats()
+{
+       int i;
+
+       for (i = 0; i < MAXBLSTATS; ++i) {
+               switch(blstats[0][i].ptype) {
+                   case P_INT:
+                       blstats[0][i].ptr.a_iptr = (int *)alloc(sizeof(int));
+                       blstats[1][i].ptr.a_iptr = (int *)alloc(sizeof(int));
+                       *blstats[0][i].ptr.a_iptr = 0;
+                       *blstats[1][i].ptr.a_iptr = 0;
+                       break;
+                   case P_LNG:
+                   case P_MASK:
+                       blstats[0][i].ptr.a_lptr = (long *)alloc(sizeof(long));
+                       blstats[1][i].ptr.a_lptr = (long *)alloc(sizeof(long));
+                       *blstats[0][i].ptr.a_lptr = 0L;
+                       *blstats[1][i].ptr.a_lptr = 0L;
+                       break;
+                   case P_UINT:
+                       blstats[0][i].ptr.a_uptr = (unsigned *)alloc(sizeof(unsigned));
+                       blstats[1][i].ptr.a_uptr = (unsigned *)alloc(sizeof(unsigned));
+                       *blstats[0][i].ptr.a_uptr = 0;
+                       *blstats[1][i].ptr.a_uptr = 0;
+                       break;
+               }
+               if (blstats[0][i].valwidth) {
+                   blstats[0][i].val = (char *)alloc(blstats[0][i].valwidth);
+                   blstats[1][i].val = (char *)alloc(blstats[0][i].valwidth);
+               } else {
+                   blstats[0][i].val = (char *)0;
+                   blstats[1][i].val = (char *)0;
+               }
+               blstats[1][i].ptype = blstats[0][i].ptype;
+       }
+}
+
+void
+bot()
+{
+       char buf[BUFSZ];
+       register char *nb;
+       static boolean init = FALSE;
+       static int idx = 0, idx_p, idxmax;
+       boolean updated = FALSE;
+       unsigned ptype;
+       int i, pc, cap = near_capacity();
+       anything curr, prev;
+       boolean valset[MAXBLSTATS];
+
+       idx = (++idx % 2);
+       idx_p = ((idx+1) % 2);
+
+       /* clear the "value set" indicators */
+       (void) memset((genericptr_t)valset, 0, MAXBLSTATS * sizeof(boolean));
+
+       /*
+        *  Player name and title.
+        */
+       buf[0] = '\0';
+       Strcpy(buf, plname);
+       if('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a';
+       buf[10] = 0;
+       Sprintf(nb = eos(buf)," the ");
+       if (Upolyd) {
+               char mbot[BUFSZ];
+               int k = 0;
+
+               Strcpy(mbot, mons[u.umonnum].mname);
+               while(mbot[k] != 0) {
+                   if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) &&
+                                       'a' <= mbot[k] && mbot[k] <= 'z')
+                       mbot[k] += 'A' - 'a';
+                   k++;
+               }
+               Sprintf(nb = eos(nb), mbot);
+       } else
+               Sprintf(nb = eos(nb), rank());
+       Sprintf(blstats[idx][BL_TITLE].val, "%-29s", buf);
+
+       /* Strength */
+
+       buf[0] = '\0';
+       *(blstats[idx][BL_STR].ptr.a_iptr) = ACURR(A_STR);
+       if (ACURR(A_STR) > 18) {
+               if (ACURR(A_STR) > STR18(100))
+                   Sprintf(buf,"%2d",ACURR(A_STR)-100);
+               else if (ACURR(A_STR) < STR18(100))
+                   Sprintf(buf, "18/%02d",ACURR(A_STR)-18);
+               else
+                   Sprintf(buf,"18/**");
+       } else
+               Sprintf(buf, "%-1d",ACURR(A_STR));
+       Strcpy(blstats[idx][BL_STR].val, buf);
+       valset[BL_STR] = TRUE;          /* indicate val already set */
+
+
+       /*  Dexterity, constitution, intelligence, wisdom, charisma. */
+        
+       *(blstats[idx][BL_DX].ptr.a_iptr) = ACURR(A_DEX);
+       *(blstats[idx][BL_CO].ptr.a_iptr) = ACURR(A_CON);
+       *(blstats[idx][BL_IN].ptr.a_iptr) = ACURR(A_INT);
+       *(blstats[idx][BL_WI].ptr.a_iptr) = ACURR(A_WIS);
+       *(blstats[idx][BL_CH].ptr.a_iptr) = ACURR(A_CHA);
+
+       /* Alignment */
+
+       Sprintf(blstats[idx][BL_ALIGN].val,
+                       (u.ualign.type == A_CHAOTIC) ? "Chaotic" :
+                       (u.ualign.type == A_NEUTRAL) ? "Neutral" : "Lawful");
+
+       /* Score */
+
+       *(blstats[idx][BL_SCORE].ptr.a_lptr) =
+#ifdef SCORE_ON_BOTL
+               botl_score();
+#else
+               0;
+#endif
+       /*  Hit points  */
+
+       *(blstats[idx][BL_HP].ptr.a_iptr) = Upolyd ? u.mh : u.uhp;
+       *(blstats[idx][BL_HPMAX].ptr.a_iptr) = Upolyd ? u.mhmax : u.uhpmax;
+       if( *(blstats[idx][BL_HP].ptr.a_iptr) < 0)
+               *(blstats[idx][BL_HP].ptr.a_iptr) = 0;
+
+       /*  Dungeon level. */
+
+       (void) describe_level(blstats[idx][BL_LEVELDESC].val);
+
+       /* Gold */
+
+       *(blstats[idx][BL_GOLD].ptr.a_lptr) =
+#ifndef GOLDOBJ
+                  u.ugold;
+#else
+                  money_cnt(invent);
+#endif
+       Sprintf(blstats[idx][BL_GOLD].val, "%c:%ld",
+                       oc_syms[COIN_CLASS], *(blstats[idx][BL_GOLD].ptr.a_lptr));
+       valset[BL_GOLD] = TRUE;         /* indicate val already set */
+
+       /* Power (magical energy) */
+
+       *(blstats[idx][BL_ENE].ptr.a_iptr) = u.uen;
+       *(blstats[idx][BL_ENEMAX].ptr.a_iptr) = u.uenmax;
+
+       /* Armor class */
+
+       *(blstats[idx][BL_AC].ptr.a_iptr) = u.uac;
+
+       /* Monster level (if Upolyd) */
+
+       if (Upolyd)
+               *(blstats[idx][BL_HD].ptr.a_iptr) = mons[u.umonnum].mlevel;
+       else
+               *(blstats[idx][BL_HD].ptr.a_iptr) = 0;
+
+       /* Experience */
+
+       *(blstats[idx][BL_XP].ptr.a_iptr) = u.ulevel;
+       *(blstats[idx][BL_EXP].ptr.a_lptr) = u.uexp;
+
+       /* Time (moves) */
+
+       *(blstats[idx][BL_TIME].ptr.a_lptr)  = moves;
+
+       /* Hunger */
+
+       *(blstats[idx][BL_HUNGER].ptr.a_uptr) = u.uhs;
+       *(blstats[idx][BL_HUNGER].val) = '\0';
+       if(strcmp(hu_stat[u.uhs], "        ") != 0)
+               Strcpy(blstats[idx][BL_HUNGER].val, hu_stat[u.uhs]);
+       valset[BL_HUNGER] = TRUE;
+
+       /* Carrying capacity */
+
+       *(blstats[idx][BL_CAP].val) = '\0';
+       *(blstats[idx][BL_CAP].ptr.a_iptr) = cap;
+       if(cap > UNENCUMBERED)
+               Strcpy(blstats[idx][BL_CAP].val, enc_stat[cap]);
+       valset[BL_CAP] = TRUE;
+
+       /* Conditions */
+
+       if (Blind) *(blstats[idx][BL_CONDITION].ptr.a_lptr) |= BL_MASK_BLIND;
+       else *(blstats[idx][BL_CONDITION].ptr.a_lptr) &= ~BL_MASK_BLIND;
+       
+       if (Confusion) *(blstats[idx][BL_CONDITION].ptr.a_lptr) |= BL_MASK_CONF;
+       else *(blstats[idx][BL_CONDITION].ptr.a_lptr) &= ~BL_MASK_CONF;
+
+       if (Sick && u.usick_type & SICK_VOMITABLE)
+               *(blstats[idx][BL_CONDITION].ptr.a_lptr) |= BL_MASK_FOODPOIS;
+       else *(blstats[idx][BL_CONDITION].ptr.a_lptr) &= ~BL_MASK_FOODPOIS;
+
+       if (Sick && u.usick_type & SICK_NONVOMITABLE)
+               *(blstats[idx][BL_CONDITION].ptr.a_lptr) |= BL_MASK_ILL;
+       else *(blstats[idx][BL_CONDITION].ptr.a_lptr) &= ~BL_MASK_ILL;
+                               
+       if (Hallucination) *(blstats[idx][BL_CONDITION].ptr.a_lptr) |= BL_MASK_HALLU;
+       else *(blstats[idx][BL_CONDITION].ptr.a_lptr) &= ~BL_MASK_HALLU;
+       
+       if (Stunned) *(blstats[idx][BL_CONDITION].ptr.a_lptr) |= BL_MASK_STUNNED;
+       else *(blstats[idx][BL_CONDITION].ptr.a_lptr) &= ~BL_MASK_STUNNED;
+
+       if (Slimed) *(blstats[idx][BL_CONDITION].ptr.a_lptr) |= BL_MASK_SLIMED;
+       else *(blstats[idx][BL_CONDITION].ptr.a_lptr) &= ~BL_MASK_SLIMED;
+       
+       /*
+        *  Now pass the changed values to window port.
+        */
+       for (i = 0; i < MAXBLSTATS; i++) {
+               if (((i == BL_SCORE) && !flags.showscore) ||
+                   ((i == BL_EXP)   && !flags.showexp)   ||
+                   ((i == BL_TIME)  && !flags.time)      ||
+                   ((i == BL_HD)    && !Upolyd))
+                       continue;
+               ptype = blstats[idx][i].ptype;
+               switch (ptype) {
+                   case P_INT:
+                           curr.a_iptr = blstats[idx][i].ptr.a_iptr;
+                           prev.a_iptr = blstats[idx_p][i].ptr.a_iptr;
+                           if (update_all || (*curr.a_iptr != *prev.a_iptr)) {
+                               idxmax = blstats[idx][i].idxmax;
+                               pc = (idxmax) ? percentage(*curr.a_iptr,
+                                       *(blstats[idx][idxmax].ptr.a_iptr)) : 0;
+                               if (!valset[i])
+                                       Sprintf(blstats[idx][i].val,
+                                               "%d", *curr.a_iptr);
+                               status_update(i,
+                                   (genericptr_t)blstats[idx][i].val,
+                                   (update_all || *curr.a_iptr > *prev.a_iptr) ?
+                                       1 : -1, pc);
+                               updated = TRUE;
+                           }
+                           break;
+                   case P_LNG:
+                           curr.a_lptr = blstats[idx][i].ptr.a_lptr;
+                           prev.a_lptr = blstats[idx_p][i].ptr.a_lptr;
+                           if (update_all || (*curr.a_lptr != *prev.a_lptr)) {
+                               idxmax = blstats[idx][i].idxmax;
+                               pc = (idxmax) ? percentagel(*curr.a_lptr,
+                                       *(blstats[idx][idxmax].ptr.a_lptr)) : 0;
+                               if (!valset[i])
+                                       Sprintf(blstats[idx][i].val,
+                                               "%-1ld", *curr.a_lptr);
+                               status_update(i,
+                                   (genericptr_t)blstats[idx][i].val,
+                                   (update_all || *curr.a_lptr > *prev.a_lptr) ?
+                                       1 : -1, pc);
+                               updated = TRUE;
+                           }
+                           break;
+                   case P_UINT:
+                           curr.a_uptr = blstats[idx][i].ptr.a_uptr;
+                           prev.a_uptr = blstats[idx_p][i].ptr.a_uptr;
+                           if (update_all || (*curr.a_uptr != *prev.a_uptr)) {
+                       /*
+                        *      idxmax = blstats[idx][i].idxmax);
+                        *      pc = (idxmax) ? percentage(*curr.a_uptr,
+                        *              *(blstats[idx][idxmax].ptr.a_uptr)) : 0;
+                        *      status_via_win(i, val,
+                        *           (*curr.a_uptr > *prev.a_uptr) ? 1 : -1, pc);
+                        */
+                               if (!valset[i])
+                                       Sprintf(blstats[idx][i].val,
+                                               "%u", *curr.a_uptr);
+                               status_update(i,
+                                   (genericptr_t)blstats[idx][i].val,
+                                    (update_all || *curr.a_uptr > *prev.a_uptr) ?
+                                       1 : -1, 0);
+                               updated = TRUE;
+                           }
+                           break;
+                   case P_STR:
+                           if (update_all ||
+                               strcmp(blstats[idx][i].val, blstats[idx_p][i].val)) {
+                               status_update(i,
+                                   (genericptr_t) blstats[idx][i].val,0,0);
+                               updated = TRUE;
+                           }
+                           break;
+                   case P_MASK:
+                           curr.a_lptr = blstats[idx][i].ptr.a_lptr;
+                           prev.a_lptr = blstats[idx_p][i].ptr.a_lptr;
+                           if (update_all || (*curr.a_lptr != *prev.a_lptr)) {
+                               status_update(i,
+                                   /* send the actual mask, not a pointer to it */
+                                   (genericptr_t)*curr.a_lptr,0,0);
+                               updated = TRUE;
+                           }
+                           break;
+               }
+       }
+       /*
+        * It is possible to get here, with nothing having been pushed
+        * to the window port, when none of the info has changed. In that
+        * case, we need to force a call to status_update() when
+        * context.botlx is set. The tty port in particular has a problem
+        * if that isn't done, since it sets context.botlx when a menu or
+        * text display obliterates the status line.
+        *
+        * To work around it, we call status_update() with ficticious
+        * index of BL_FLUSH (-1).
+        */
+       if (context.botlx && !updated)
+               status_update(BL_FLUSH,(genericptr_t)0,0,0);
+
+       context.botl = context.botlx = 0;
+       update_all = FALSE;
+}
+
+/*****************************************************************************/
+/* genl backward compat stuff - probably doesn't belong in botl.c any longer */
+/*****************************************************************************/
+
+const char *fieldnm[MAXBLSTATS];
+const char *fieldfmt[MAXBLSTATS];
+char *vals[MAXBLSTATS];
+boolean activefields[MAXBLSTATS];
+NEARDATA winid WIN_STATUS;
+
+void
+genl_status_init()
+{
+       int i;
+       for (i = 0; i < MAXBLSTATS; ++i) {
+               vals[i] = (char *)alloc(MAXCO);
+               *vals[i] = '\0';
+               activefields[i] = FALSE;
+               fieldfmt[i] = FALSE;
+       }
+       /* Use a window for the genl version; backward port compatibility */
+       WIN_STATUS = create_nhwindow(NHW_STATUS);
+       display_nhwindow(WIN_STATUS, FALSE);
+}
+
+void
+genl_status_finish()
+{
+       /* tear down routine */
+       int i;
+
+       /* free alloc'd memory here */
+       for (i = 0; i < MAXBLSTATS; ++i)
+               free((genericptr_t)vals[i]);
+}
+
+void
+genl_status_enablefield(fieldidx, nm, fmt, enable)
+int fieldidx;
+const char *nm;
+const char *fmt;
+boolean enable;
+{
+       fieldfmt[fieldidx] = fmt;
+       fieldnm[fieldidx] = nm;
+       activefields[fieldidx] = enable;
+}
+
+void
+genl_status_update(idx, ptr, chg, percent)
+int idx, chg, percent;
+genericptr_t ptr;
+{
+       char newbot1[MAXCO], newbot2[MAXCO];
+       static int init = FALSE;
+       long cond;
+       register int i;
+       int fieldorder1[] = {
+                BL_TITLE, BL_STR, BL_DX,BL_CO, BL_IN,
+                BL_WI, BL_CH,BL_ALIGN, BL_SCORE, -1
+               };
+       int fieldorder2[] = {
+                BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX,
+                BL_ENE, BL_ENEMAX, BL_AC, BL_XP, BL_EXP, BL_TIME,
+                BL_HUNGER,BL_CAP, BL_CONDITION, -1
+               };
+
+       if (idx != BL_FLUSH) {
+           if (!activefields[idx]) return;
+           switch(idx) {
+               case BL_CONDITION:
+                       cond = (long)ptr;
+                       *vals[idx] = '\0';
+                       if (cond & BL_MASK_BLIND) Strcat(vals[idx], " Blind");
+                       if (cond & BL_MASK_CONF) Strcat(vals[idx], " Conf");
+                       if (cond & BL_MASK_FOODPOIS)
+                                       Strcat(vals[idx], " FoodPois");
+                       if (cond & BL_MASK_ILL) Strcat(vals[idx], " Ill");
+                       if (cond & BL_MASK_STUNNED) Strcat(vals[idx], " Hallu");
+                       if (cond & BL_MASK_HALLU) Strcat(vals[idx], " Stun");
+                       if (cond & BL_MASK_SLIMED) Strcat(vals[idx], " Slime");
+                       break;
+               default:
+                       (void) Sprintf(vals[idx],
+                                       fieldfmt[idx] ? fieldfmt[idx] : "%s",
+                                       (char *)ptr, MAXCO);
+                       break;
+           }
+       }
+
+       /* This genl version updates everything on the display, evertime */
+       newbot1[0] = '\0';
+       for (i = 0; fieldorder1[i] >= 0; ++i) {
+           int idx = fieldorder1[i];
+           if (activefields[idx])
+               Strcat(newbot1, vals[idx]);
+       }
+       newbot2[0] = '\0';
+       for (i = 0; fieldorder2[i] >= 0; ++i) {
+           int idx = fieldorder2[i];
+           if (activefields[idx])
+               Strcat(newbot2, vals[idx]);
+       }
+       curs(WIN_STATUS, 1, 0);
+       putstr(WIN_STATUS, 0, newbot1);
+       curs(WIN_STATUS, 1, 1);
+       putstr(WIN_STATUS, 0, newbot2);
+}
+#endif /*STATUS_VIA_WINDOWPORT*/
+
 /*botl.c*/
+
+
index 0de6fee8d0200651bae535a1af36730453a1bfc5..9247fd961f8cab03207d991071803d322092fc9c 100644 (file)
@@ -255,7 +255,10 @@ NEARDATA boolean vision_full_recalc = 0;
 NEARDATA char   **viz_array = 0;/* used in cansee() and couldsee() macros */
 
 /* Global windowing data, defined here for multi-window-system support */
-NEARDATA winid WIN_MESSAGE = WIN_ERR, WIN_STATUS = WIN_ERR;
+NEARDATA winid WIN_MESSAGE = WIN_ERR;
+#ifndef STATUS_VIA_WINDOWPORT
+NEARDATA WIN_STATUS = WIN_ERR;
+#endif
 NEARDATA winid WIN_MAP = WIN_ERR, WIN_INVEN = WIN_ERR;
 char toplines[TBUFSZ];
 /* Windowing stuff that's really tty oriented, but present for all ports */
index cf33ef4b71138ec54bb84b682e66e1fe37905489..70858f626f02d17ffd14dc43865efe871497a5ac 100644 (file)
--- a/src/end.c
+++ b/src/end.c
@@ -768,10 +768,17 @@ die:
            wait_synch();
            display_nhwindow(WIN_MESSAGE, TRUE);
            destroy_nhwindow(WIN_MAP);
+#ifdef STATUS_VIA_WINDOWPORT
+           status_finish();
+#else
            destroy_nhwindow(WIN_STATUS);
+#endif
            destroy_nhwindow(WIN_MESSAGE);
+#ifdef STATUS_VIA_WINDOWPORT
+           WIN_MESSAGE = WIN_MAP = WIN_ERR;
+#else
            WIN_MESSAGE = WIN_STATUS = WIN_MAP = WIN_ERR;
-
+#endif
            if(!done_stopprint || flags.tombstone)
                endwin = create_nhwindow(NHW_TEXT);
 
index 2df48da52eaae3c3c2784e2214c2d0415bf38d18..a0d51c899d261d02ffc54ad932c40d7a371d0cb6 100644 (file)
@@ -26,6 +26,12 @@ NEARDATA struct instance_flags iflags;       /* provide linkage */
 #define PREFER_TILED FALSE
 #endif
 
+#define MESSAGE_OPTION 1
+#define STATUS_OPTION  2
+#define MAP_OPTION     3
+#define MENU_OPTION    4
+#define TEXT_OPTION    5
+
 /*
  *  NOTE:  If you add (or delete) an option, please update the short
  *  options help (option_help()), the long options help (dat/opthelp),
@@ -1188,55 +1194,55 @@ boolean tinitial, tfrom_file;
        fullname = "font";
        if (!strncmpi(opts, fullname, 4))
        {
-               int wintype = -1;
+               int opttype = -1;
                char *fontopts = opts + 4;
 
                if (!strncmpi(fontopts, "map", 3) ||
                    !strncmpi(fontopts, "_map", 4))
-                       wintype = NHW_MAP;
+                       opttype = MAP_OPTION;
                else if (!strncmpi(fontopts, "message", 7) ||
                         !strncmpi(fontopts, "_message", 8))
-                       wintype = NHW_MESSAGE;
+                       opttype = MESSAGE_OPTION;
                else if (!strncmpi(fontopts, "text", 4) ||
                         !strncmpi(fontopts, "_text", 5))
-                       wintype = NHW_TEXT;                     
+                       opttype = TEXT_OPTION;                  
                else if (!strncmpi(fontopts, "menu", 4) ||
                         !strncmpi(fontopts, "_menu", 5))
-                       wintype = NHW_MENU;
+                       opttype = MENU_OPTION;
                else if (!strncmpi(fontopts, "status", 6) ||
                         !strncmpi(fontopts, "_status", 7))
-                       wintype = NHW_STATUS;
+                       opttype = STATUS_OPTION;
                else if (!strncmpi(fontopts, "_size", 5)) {
                        if (!strncmpi(fontopts, "_size_map", 8))
-                               wintype = NHW_MAP;
+                               opttype = MAP_OPTION;
                        else if (!strncmpi(fontopts, "_size_message", 12))
-                               wintype = NHW_MESSAGE;
+                               opttype = MESSAGE_OPTION;
                        else if (!strncmpi(fontopts, "_size_text", 9))
-                               wintype = NHW_TEXT;
+                               opttype = TEXT_OPTION;
                        else if (!strncmpi(fontopts, "_size_menu", 9))
-                               wintype = NHW_MENU;
+                               opttype = MENU_OPTION;
                        else if (!strncmpi(fontopts, "_size_status", 11))
-                               wintype = NHW_STATUS;
+                               opttype = STATUS_OPTION;
                        else {
                                badoption(opts);
                                return;
                        }
-                       if (wintype > 0 && !negated &&
+                       if (opttype > 0 && !negated &&
                            (op = string_for_opt(opts, FALSE)) != 0) {
-                           switch(wintype)  {
-                               case NHW_MAP:
+                           switch(opttype)  {
+                               case MAP_OPTION:
                                        iflags.wc_fontsiz_map = atoi(op);
                                        break;
-                               case NHW_MESSAGE:
+                               case MESSAGE_OPTION:
                                        iflags.wc_fontsiz_message = atoi(op);
                                        break;
-                               case NHW_TEXT:
+                               case TEXT_OPTION:
                                        iflags.wc_fontsiz_text = atoi(op);
                                        break;
-                               case NHW_MENU:
+                               case MENU_OPTION:
                                        iflags.wc_fontsiz_menu = atoi(op);
                                        break;
-                               case NHW_STATUS:
+                               case STATUS_OPTION:
                                        iflags.wc_fontsiz_status = atoi(op);
                                        break;
                            }
@@ -1245,11 +1251,11 @@ boolean tinitial, tfrom_file;
                } else {
                        badoption(opts);
                }
-               if (wintype > 0 &&
+               if (opttype > 0 &&
                    (op = string_for_opt(opts, FALSE)) != 0) {
-                       wc_set_font_name(wintype, op);
+                       wc_set_font_name(opttype, op);
 #ifdef MAC
-                       set_font_name (wintype, op);
+                       set_font_name (opttype, op);
 #endif
                        return;
                } else if (negated) bad_negation(fullname, TRUE);
@@ -2204,9 +2210,12 @@ goodfruit:
 #ifdef SCORE_ON_BOTL
                         || (boolopt[i].addr) == &flags.showscore
 #endif
-                           )
+                           ) {
+#ifdef STATUS_VIA_WINDOWPORT
+                           status_initialize(TRUE);   /* TRUE = reassess only */
+#endif
                            context.botl = TRUE;
-
+                       }
                        else if ((boolopt[i].addr) == &flags.invlet_constant) {
                            if (flags.invlet_constant) reassign();
                        }
@@ -3745,26 +3754,26 @@ const char *optnam;
 
 
 STATIC_OVL void
-wc_set_font_name(wtype, fontname)
-int wtype;
+wc_set_font_name(opttype, fontname)
+int opttype;
 char *fontname;
 {
        char **fn = (char **)0;
        if (!fontname) return;
-       switch(wtype) {
-           case NHW_MAP:
+       switch(opttype) {
+           case MAP_OPTION:
                        fn = &iflags.wc_font_map;
                        break;
-           case NHW_MESSAGE:
+           case MESSAGE_OPTION:
                        fn = &iflags.wc_font_message;
                        break;
-           case NHW_TEXT:
+           case TEXT_OPTION:
                        fn = &iflags.wc_font_text;
                        break;
-           case NHW_MENU:
+           case MENU_OPTION:
                        fn = &iflags.wc_font_menu;
                        break;
-           case NHW_STATUS:
+           case STATUS_OPTION:
                        fn = &iflags.wc_font_status;
                        break;
            default:
index 890f143852af78fc10426331ad017e4f0f55d7f7..2710777ced740a57ff12b874a1c52a610f6aaea4 100644 (file)
@@ -1112,8 +1112,10 @@ freedynamicdata()
 #ifdef AUTOPICKUP_EXCEPTIONS
        free_autopickup_exceptions();
 #endif
-
 #endif /* FREE_ALL_MEMORY */
+#ifdef STATUS_VIA_WINDOWPORT
+       status_finish();
+#endif
        return;
 }