window port change - putmixed() (trunk only)
Add putmixed() to the window port. It allows map symbols to be included in the string by encoding them in a unique fashion. This was done because Unicode symbols, for instance, could be longer than the size of a char. The encoding of the map symbols in this patch is done by prefixing a glyph value with \GXXXX, where XXXX is a random value for the current game. The reason for the random prefix is to minimize the possibility that a player can trigger the escape sequence processing within text under their control (dog names, etc.) the way they could if the sequence was fixed in the source code. The random prefix remains the same throughout the lifetime of a game because message window strings are saved in the save file. (There was actually a bug present because of the embedded character even before the recent symbol changes, because if someone was using a different set of characters between games, the saved messages would reflect the original characters, rather than the current. That bug was introduced with the ability to save messages to the savefile.) A window port does not have to supply an XXX_putmixed() routine, it can use genl_putmixed() which uses the old behavior of embedding the sequence as a character within the string and calling putstr(). genl_putmixed() takes care of the decoding of the escape sequence. This also #ifdef's out code in pager.c for converting a glyph to a character, and uses mapglyph() to do that instead. Does anyone see a problem with doing that through mapglyph instead of repeating similar code within pager.c?
This commit is contained in:
@@ -52,6 +52,7 @@ boolean resuming;
|
||||
}
|
||||
|
||||
if (!resuming) { /* new game */
|
||||
context.rndencode = rnd(9000);
|
||||
set_wear(); /* handle side-effects of worn starting gear */
|
||||
(void) pickup(1); /* autopickup at initial location */
|
||||
} else {
|
||||
|
||||
@@ -331,7 +331,7 @@ struct istat_s blstats[2][MAXBLSTATS] = {
|
||||
{ 0L, ANY_STR, {(genericptr_t)0L}, (char *)0, 40, 0}, /* 7 BL_ALIGN */
|
||||
{ 0L, ANY_LONG, {(genericptr_t)0L}, (char *)0, 20, 0}, /* 8 BL_SCORE */
|
||||
{ 0L, ANY_LONG, {(genericptr_t)0L}, (char *)0, 20, 0}, /* 9 BL_CAP */
|
||||
{ 0L, ANY_LONG, {(genericptr_t)0L}, (char *)0, 10, 0}, /* 10 BL_GOLD */
|
||||
{ 0L, ANY_LONG, {(genericptr_t)0L}, (char *)0, 30, 0}, /* 10 BL_GOLD */
|
||||
{ 0L, ANY_INT, {(genericptr_t)0L}, (char *)0, 10, BL_ENEMAX}, /* 11 BL_ENE */
|
||||
{ 0L, ANY_INT, {(genericptr_t)0L}, (char *)0, 10, 0}, /* 12 BL_ENEMAX */
|
||||
{ 0L, ANY_LONG, {(genericptr_t)0L}, (char *)0, 10, 0}, /* 13 BL_XP */
|
||||
@@ -727,8 +727,9 @@ bot()
|
||||
* the rogue level.
|
||||
*/
|
||||
|
||||
Sprintf(blstats[idx][BL_GOLD].val, "%c:%ld",
|
||||
showsyms[COIN_CLASS + SYM_OFF_O],
|
||||
Sprintf(blstats[idx][BL_GOLD].val,
|
||||
"%s:%ld",
|
||||
encglyph(objnum_to_glyph(GOLD_PIECE)),
|
||||
blstats[idx][BL_GOLD].a.a_long);
|
||||
valset[BL_GOLD] = TRUE; /* indicate val already set */
|
||||
|
||||
@@ -1451,7 +1452,7 @@ genericptr_t ptr;
|
||||
curs(WIN_STATUS, 1, 0);
|
||||
putstr(WIN_STATUS, 0, newbot1);
|
||||
curs(WIN_STATUS, 1, 1);
|
||||
putstr(WIN_STATUS, 0, newbot2);
|
||||
putmixed(WIN_STATUS, 0, newbot2); /* putmixed() due to GOLD glyph */
|
||||
}
|
||||
|
||||
#endif /*STATUS_VIA_WINDOWPORT*/
|
||||
|
||||
@@ -254,4 +254,83 @@ unsigned *ospecial;
|
||||
return idx;
|
||||
}
|
||||
|
||||
char *
|
||||
encglyph(glyph)
|
||||
int glyph;
|
||||
{
|
||||
static char encbuf[20];
|
||||
Sprintf(encbuf, "\\G%04X%04X", context.rndencode, glyph);
|
||||
return encbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* This differs from putstr() because the str parameter can
|
||||
* contain a sequence of characters representing:
|
||||
* \GXXXXNNNN a glyph value, encoded by encglyph().
|
||||
*
|
||||
* For window ports that haven't yet written their own
|
||||
* XXX_putmixed() routine, this general one can be used.
|
||||
* It replaces the encoded glyph sequence with a single
|
||||
* showsyms[] char, then just passes that string onto
|
||||
* putstr().
|
||||
*/
|
||||
|
||||
void
|
||||
genl_putmixed(window, attr, str)
|
||||
winid window;
|
||||
int attr;
|
||||
const char *str;
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
const char *cp = str;
|
||||
char *put = buf;
|
||||
while (*cp) {
|
||||
if (*cp == '\\') {
|
||||
int rndchk = 0, so = 0, gv = 0, ch, oc, dcount;
|
||||
unsigned os;
|
||||
const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
|
||||
const char *save_cp = cp;
|
||||
|
||||
cp++;
|
||||
switch(*cp) {
|
||||
case 'G': /* glyph value \GXXXXNNNN*/
|
||||
dcount = 0;
|
||||
for (++cp; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
|
||||
rndchk = (int)((rndchk * 16) + ((int)(dp - hex) / 2));
|
||||
|
||||
if (rndchk == context.rndencode) {
|
||||
dcount = 0;
|
||||
for (; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
|
||||
gv = (int)((gv * 16) + ((int)(dp - hex) / 2));
|
||||
so = mapglyph(gv, &ch, &oc, &os, 0, 0);
|
||||
*put++ = showsyms[so];
|
||||
} else {
|
||||
/* possible forgery - leave it the way it is */
|
||||
cp = save_cp;
|
||||
}
|
||||
break;
|
||||
# if 0
|
||||
case 'S': /* symbol offset */
|
||||
dcount = 0;
|
||||
for (++cp; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
|
||||
rndchk = (int)((rndchk * 16) + ((int)(dp - hex) / 2));
|
||||
|
||||
if (rndchk == context.rndencode) {
|
||||
dcount = 0;
|
||||
for (; *cp && (dp = index(hex, *cp)) && (dcount++ < 2); cp++)
|
||||
so = (int)((so * 16) + ((int)(dp - hex) / 2));
|
||||
}
|
||||
*put++ = showsyms[so];
|
||||
break;
|
||||
# endif
|
||||
case '\\':
|
||||
break;
|
||||
}
|
||||
}
|
||||
*put++ = *cp++;
|
||||
}
|
||||
*put = '\0';
|
||||
/* now send it to the normal putstr */
|
||||
putstr(window, attr, buf);
|
||||
}
|
||||
/*mapglyph.c*/
|
||||
|
||||
47
src/pager.c
47
src/pager.c
@@ -466,6 +466,7 @@ do_look(mode, click_cc)
|
||||
char out_str[BUFSZ], look_buf[BUFSZ];
|
||||
const char *x_str, *firstmatch = 0;
|
||||
struct permonst *pm = 0;
|
||||
int glyph; /* glyph at selected position */
|
||||
int i, ans = 0;
|
||||
int sym; /* typed symbol or converted glyph */
|
||||
int found; /* count of matching syms found */
|
||||
@@ -522,8 +523,8 @@ do_look(mode, click_cc)
|
||||
out_str[0] = '\0';
|
||||
|
||||
if (from_screen || clicklook) {
|
||||
int glyph; /* glyph at selected position */
|
||||
|
||||
int oc, so;
|
||||
unsigned os;
|
||||
if (from_screen) {
|
||||
if (flags.verbose)
|
||||
pline("Please move the cursor to %s.",
|
||||
@@ -538,9 +539,10 @@ do_look(mode, click_cc)
|
||||
}
|
||||
flags.verbose = FALSE; /* only print long question once */
|
||||
}
|
||||
glyph = glyph_at(cc.x,cc.y);
|
||||
|
||||
/* Convert the glyph at the selected position to a symbol. */
|
||||
glyph = glyph_at(cc.x,cc.y);
|
||||
#if 0
|
||||
if (glyph_is_cmap(glyph)) {
|
||||
sym = showsyms[glyph_to_cmap(glyph)];
|
||||
} else if (glyph_is_trap(glyph)) {
|
||||
@@ -566,6 +568,8 @@ do_look(mode, click_cc)
|
||||
glyph, (int)cc.x, (int)cc.y);
|
||||
sym = ' ';
|
||||
}
|
||||
#endif
|
||||
so = mapglyph(glyph, &sym, &oc, &os, cc.x, cc.y);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -580,7 +584,9 @@ do_look(mode, click_cc)
|
||||
def_monsyms[i].explain) {
|
||||
need_to_look = TRUE;
|
||||
if (!found) {
|
||||
Sprintf(out_str, "%c %s", sym, an(def_monsyms[i].explain));
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph),
|
||||
an(def_monsyms[i].explain));
|
||||
firstmatch = def_monsyms[i].explain;
|
||||
found++;
|
||||
} else {
|
||||
@@ -604,7 +610,8 @@ do_look(mode, click_cc)
|
||||
*/
|
||||
if (u.uswallow && (from_screen || clicklook) && is_swallow_sym(sym)) {
|
||||
if (!found) {
|
||||
Sprintf(out_str, "%c %s", sym, mon_interior);
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph), mon_interior);
|
||||
firstmatch = mon_interior;
|
||||
} else {
|
||||
found += append_str(out_str, mon_interior);
|
||||
@@ -622,7 +629,9 @@ do_look(mode, click_cc)
|
||||
continue;
|
||||
}
|
||||
if (!found) {
|
||||
Sprintf(out_str, "%c %s", sym, an(def_oc_syms[i].explain));
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph),
|
||||
an(def_oc_syms[i].explain));
|
||||
firstmatch = def_oc_syms[i].explain;
|
||||
found++;
|
||||
} else {
|
||||
@@ -633,7 +642,9 @@ do_look(mode, click_cc)
|
||||
|
||||
if (sym == DEF_INVISIBLE) {
|
||||
if (!found) {
|
||||
Sprintf(out_str, "%c %s", sym, an(invisexplain));
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph),
|
||||
an(invisexplain));
|
||||
firstmatch = invisexplain;
|
||||
found++;
|
||||
} else {
|
||||
@@ -656,10 +667,12 @@ do_look(mode, click_cc)
|
||||
|
||||
if (!found) {
|
||||
if (is_cmap_trap(i)) {
|
||||
Sprintf(out_str, "%c a trap", sym);
|
||||
Sprintf(out_str, "%s a trap",
|
||||
encglyph(glyph));
|
||||
hit_trap = TRUE;
|
||||
} else {
|
||||
Sprintf(out_str, "%c %s", sym,
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph),
|
||||
article == 2 ? the(x_str) :
|
||||
article == 1 ? an(x_str) : x_str);
|
||||
}
|
||||
@@ -684,8 +697,8 @@ do_look(mode, click_cc)
|
||||
if (sym == ((from_screen || clicklook) ?
|
||||
warnsyms[i] : def_warnsyms[i].sym)) {
|
||||
if (!found) {
|
||||
Sprintf(out_str, "%c %s",
|
||||
sym, def_warnsyms[i].explanation);
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph), def_warnsyms[i].explanation);
|
||||
firstmatch = def_warnsyms[i].explanation;
|
||||
found++;
|
||||
} else {
|
||||
@@ -703,7 +716,8 @@ do_look(mode, click_cc)
|
||||
if (skipped_venom && found < 2) {
|
||||
x_str = def_oc_syms[VENOM_CLASS].explain;
|
||||
if (!found) {
|
||||
Sprintf(out_str, "%c %s", sym, an(x_str));
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph), an(x_str));
|
||||
firstmatch = x_str;
|
||||
found++;
|
||||
} else {
|
||||
@@ -715,7 +729,8 @@ do_look(mode, click_cc)
|
||||
if (iflags.bouldersym && sym == iflags.bouldersym) {
|
||||
if (!found) {
|
||||
firstmatch = "boulder";
|
||||
Sprintf(out_str, "%c %s", sym, an(firstmatch));
|
||||
Sprintf(out_str, "%s %s",
|
||||
encglyph(glyph), an(firstmatch));
|
||||
found++;
|
||||
} else {
|
||||
found += append_str(out_str, "boulder");
|
||||
@@ -747,7 +762,10 @@ do_look(mode, click_cc)
|
||||
|
||||
/* Finally, print out our explanation. */
|
||||
if (found) {
|
||||
pline("%s", out_str);
|
||||
|
||||
/* Used putmixed() because there may be an encoded glyph present */
|
||||
putmixed(WIN_MESSAGE, 0, out_str);
|
||||
|
||||
/* check the data file for information about this thing */
|
||||
if (found == 1 && ans != LOOK_QUICK && ans != LOOK_ONCE &&
|
||||
(ans == LOOK_VERBOSE || (flags.help && !quick)) && !clicklook) {
|
||||
@@ -765,7 +783,6 @@ do_look(mode, click_cc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dowhatis()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user