status display - core modules (trunk only)

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.
This commit is contained in:
nethack.allison
2003-11-23 06:43:17 +00:00
parent 2db57166dc
commit 5ed547995d
12 changed files with 697 additions and 54 deletions

View 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.

View 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 */

View 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

View 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 ### */

View 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

View 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 */

View 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);

View 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*/

View 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 */

View File

@@ -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);

View 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:

View 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;
}