diff --git a/src/botl.c b/src/botl.c index 49cb38154..30705c6e0 100644 --- a/src/botl.c +++ b/src/botl.c @@ -652,7 +652,8 @@ bot() * To work around it, we call status_update() with fictitious * index of BL_FLUSH (-1). */ - if (context.botlx && !updated) + if ((context.botlx && !updated) + || windowprocs.win_status_update == genl_status_update) status_update(BL_FLUSH, (genericptr_t) 0, 0, 0); context.botl = context.botlx = 0; @@ -796,7 +797,7 @@ boolean (!flags.showexp || Upolyd) ? FALSE : TRUE); break; case BL_CONDITION: - fieldfmt = "%S"; + fieldfmt = "%s"; fieldname = "condition"; status_enablefield(fld, fieldname, fieldfmt, TRUE); break; diff --git a/src/windows.c b/src/windows.c index ce6691347..bdbd76e2d 100644 --- a/src/windows.c +++ b/src/windows.c @@ -817,6 +817,7 @@ void genl_status_init() { int i; + for (i = 0; i < MAXBLSTATS; ++i) { status_vals[i] = (char *) alloc(MAXCO); *status_vals[i] = '\0'; @@ -837,8 +838,7 @@ genl_status_finish() /* free alloc'd memory here */ for (i = 0; i < MAXBLSTATS; ++i) { if (status_vals[i]) - free((genericptr_t) status_vals[i]); - status_vals[i] = (char *) 0; + free((genericptr_t) status_vals[i]), status_vals[i] = (char *) 0; } } @@ -854,6 +854,7 @@ boolean enable; status_activefields[fieldidx] = enable; } +/* call once for each field, then call with BL_FLUSH to output the result */ void genl_status_update(idx, ptr, chg, percent) int idx; @@ -863,15 +864,37 @@ int chg UNUSED, percent UNUSED; char newbot1[MAXCO], newbot2[MAXCO]; long cond, *condptr = (long *) ptr; register int i; - char *text = (char *) ptr; + unsigned pass, lndelta; + enum statusfields idx1, idx2, *fieldlist; + char *nb, *text = (char *) ptr; - enum statusfields fieldorder[2][15] = { + static enum statusfields fieldorder[][15] = { + /* line one */ { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_ALIGN, BL_SCORE, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH }, - { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, - BL_AC, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_HUNGER, - BL_CAP, BL_CONDITION, BL_FLUSH } + /* line two, default order */ + { BL_LEVELDESC, BL_GOLD, + BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC, + BL_XP, BL_EXP, BL_HD, + BL_TIME, + BL_HUNGER, BL_CAP, BL_CONDITION, + BL_FLUSH }, + /* move time to the end */ + { BL_LEVELDESC, BL_GOLD, + BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC, + BL_XP, BL_EXP, BL_HD, + BL_HUNGER, BL_CAP, BL_CONDITION, + BL_TIME, BL_FLUSH }, + /* move experience and time to the end */ + { BL_LEVELDESC, BL_GOLD, + BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC, + BL_HUNGER, BL_CAP, BL_CONDITION, + BL_XP, BL_EXP, BL_HD, BL_TIME, BL_FLUSH }, + /* move level description plus gold and experience and time to end */ + { BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, BL_AC, + BL_HUNGER, BL_CAP, BL_CONDITION, + BL_LEVELDESC, BL_GOLD, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_FLUSH }, }; if (idx != BL_FLUSH) { @@ -880,54 +903,117 @@ int chg UNUSED, percent UNUSED; switch (idx) { case BL_CONDITION: cond = *condptr; - *status_vals[idx] = '\0'; + nb = status_vals[idx]; + *nb = '\0'; if (cond & BL_MASK_STONE) - Strcat(status_vals[idx], " Stone"); + Strcpy(nb = eos(nb), " Stone"); if (cond & BL_MASK_SLIME) - Strcat(status_vals[idx], " Slime"); + Strcpy(nb = eos(nb), " Slime"); if (cond & BL_MASK_STRNGL) - Strcat(status_vals[idx], " Strngl"); + Strcpy(nb = eos(nb), " Strngl"); if (cond & BL_MASK_FOODPOIS) - Strcat(status_vals[idx], " FoodPois"); + Strcpy(nb = eos(nb), " FoodPois"); if (cond & BL_MASK_TERMILL) - Strcat(status_vals[idx], " TermIll"); + Strcpy(nb = eos(nb), " TermIll"); if (cond & BL_MASK_BLIND) - Strcat(status_vals[idx], " Blind"); + Strcpy(nb = eos(nb), " Blind"); if (cond & BL_MASK_DEAF) - Strcat(status_vals[idx], " Deaf"); + Strcpy(nb = eos(nb), " Deaf"); if (cond & BL_MASK_STUN) - Strcat(status_vals[idx], " Stun"); + Strcpy(nb = eos(nb), " Stun"); if (cond & BL_MASK_CONF) - Strcat(status_vals[idx], " Conf"); + Strcpy(nb = eos(nb), " Conf"); if (cond & BL_MASK_HALLU) - Strcat(status_vals[idx], " Hallu"); + Strcpy(nb = eos(nb), " Hallu"); if (cond & BL_MASK_LEV) - Strcat(status_vals[idx], " Lev"); + Strcpy(nb = eos(nb), " Lev"); if (cond & BL_MASK_FLY) - Strcat(status_vals[idx], " Fly"); + Strcpy(nb = eos(nb), " Fly"); if (cond & BL_MASK_RIDE) - Strcat(status_vals[idx], " Ride"); + Strcpy(nb = eos(nb), " Ride"); break; default: Sprintf(status_vals[idx], status_fieldfmt[idx] ? status_fieldfmt[idx] : "%s", text); break; } - } + return; /* processed one field other than BL_FLUSH */ + } /* (idx != BL_FLUSH) */ - /* This genl version updates everything on the display, everytime */ - newbot1[0] = '\0'; - for (i = 0; fieldorder[0][i] != BL_FLUSH; ++i) { - int idx1 = fieldorder[0][i]; + /* We've received BL_FLUSH; time to output the gathered data */ + nb = newbot1; + *nb = '\0'; + for (i = 0; (idx1 = fieldorder[0][i]) != BL_FLUSH; ++i) { if (status_activefields[idx1]) - Strcat(newbot1, status_vals[idx1]); - } - newbot2[0] = '\0'; - for (i = 0; fieldorder[1][i] != BL_FLUSH; ++i) { - int idx2 = fieldorder[1][i]; - if (status_activefields[idx2]) - Strcat(newbot2, status_vals[idx2]); + Strcpy(nb = eos(nb), status_vals[idx1]); } + /* if '$' is encoded, buffer length of \GXXXXNNNN is 9 greater than + single char; we want to subtract that 9 when checking display length */ + lndelta = (status_activefields[BL_GOLD] + && strstr(status_vals[BL_GOLD], "\\G")) ? 9 : 0; + /* basic bot2 formats groups of second line fields into five buffers, + then decides how to order those buffers based on comparing lengths + of [sub]sets of them to the width of the map; we have more control + here but currently emulate that behavior */ + for (pass = 1; pass <= 4; pass++) { + fieldlist = fieldorder[pass]; + nb = newbot2; + *nb = '\0'; + for (i = 0; (idx2 = fieldlist[i]) != BL_FLUSH; ++i) { + if (status_activefields[idx2]) { + const char *val = status_vals[idx2]; + + switch (idx2) { + case BL_HP: /* for pass 4, Hp comes first; mungspaces() + will strip the unwanted leading spaces */ + case BL_XP: case BL_HD: + case BL_TIME: + Strcpy(nb = eos(nb), " "); + break; + case BL_LEVELDESC: + /* leveldesc has no leading space, so if we've moved + it past the first position, provide one */ + if (i != 0) + Strcpy(nb = eos(nb), " "); + break; + /* + * We want " hunger encumbrance conditions" + * or " encumbrance conditions" + * or " hunger conditions" + * or " conditions" + * 'hunger' is either " " or " hunger_text"; + * 'encumbrance' is either " " or " encumbrance_text"; + * 'conditions' is either "" or " cond1 cond2...". + */ + case BL_HUNGER: + /* hunger==" " - keep it, end up with " "; + hunger!=" " - insert space and get " hunger" */ + if (strcmp(val, " ")) + Strcpy(nb = eos(nb), " "); + break; + case BL_CAP: + /* cap==" " - suppress it, retain " hunger" or " "; + cap!=" " - use it, get " hunger cap" or " cap" */ + if (!strcmp(val, " ")) + ++val; + break; + default: + break; + } + Strcpy(nb = eos(nb), val); /* status_vals[idx2] */ + } /* status_activefields[idx2] */ + + if (idx2 == BL_CONDITION && pass < 4 + && strlen(newbot2) - lndelta > COLNO) + break; /* switch to next order */ + } /* i */ + + if (idx2 == BL_FLUSH) { /* made it past BL_CONDITION */ + if (pass > 1) + mungspaces(newbot2); + break; + } + } /* pass */ curs(WIN_STATUS, 1, 0); putstr(WIN_STATUS, 0, newbot1); curs(WIN_STATUS, 1, 1); @@ -937,9 +1023,9 @@ int chg UNUSED, percent UNUSED; #ifdef STATUS_HILITES void genl_status_threshold(fldidx, thresholdtype, threshold, behavior, under, over) -int fldidx, thresholdtype; -int behavior, under, over; -anything threshold; +int fldidx UNUSED, thresholdtype UNUSED; +anything threshold UNUSED; +int behavior UNUSED, under UNUSED, over UNUSED; { return; } diff --git a/util/makedefs.c b/util/makedefs.c index a20660c7c..f8acd34a6 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1405,6 +1405,15 @@ static const char *build_opts[] = { #ifdef SHELL "shell command", #endif +#ifdef STATUS_VIA_WINDOWPORT +# ifdef STATUS_HILITES + "status via windowport with highlighting", +# else + "status via windowport without highlighting", +# endif +#else + "traditional status display", +#endif #ifdef SUSPEND "suspend command", #endif