Add orientation bit 2048, enumerated as ROTATESPRITE_FULL16, which is a courtesy provided by the engine for the purpose of the game to internally force use of full 32-bit coordinates. With this bit set, all CON screen drawing commands can use rotatesprite16-like coordinates.

While the functionality was already internally in place for gametext as one of two hacks using ROTATESPRITE_MAX (the other still used by minitext_() to align with the statusbar) we must codify a bit in the engine for safe external use. (Otherwise, ROTATESPRITE_MAX could/would theoretically increase and leave modders high and dry.)

(Dev note: In G_DrawTXDigiNumZ(), ROTATESPRITE_MAX was used to bitshift the value used to calculate digit spacing for no reason I can ascertain other than to introduce rounding errors into the zoom/textscale calculations. It was never used anywhere, so I removed it.)

Bonus: The scaling code for digitalnumberz and gametextz has been modified so that the spacing is no longer affected by rounding errors. Try animating the zoom value and compare how the text used to jump but now does not.

git-svn-id: https://svn.eduke32.com/eduke32@3608 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2013-03-25 04:31:58 +00:00
parent 4c5fd9d9e2
commit c5044b3ecd
4 changed files with 60 additions and 51 deletions

View file

@ -164,8 +164,9 @@ void yax_drawrooms(void (*SpriteAnimFunc)(int32_t,int32_t,int32_t,int32_t),
#define BXY_MAX 524288
enum {
ROTATESPRITE_FULL16 = 2048,
// ROTATESPRITE_MAX-1 is the mask of all externally available orientation bits
ROTATESPRITE_MAX = 2048,
ROTATESPRITE_MAX = 4096,
RS_CENTERORIGIN = (1<<30),
};

View file

@ -317,22 +317,22 @@ int32_t G_PrintGameText(int32_t f, int32_t tile, int32_t x, int32_t y, const
int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z)
{
int32_t ac;
char centre;
const int32_t squishtext = ((f&2) != 0);
int32_t shift = 16, widthx = 320;
int32_t ox, oy, origx = x, origy = y;
const int32_t squishtext = (f&2) != 0 ? 1 : 0;
const int32_t widthx = 320<<16;
int32_t origx = x, origy, j = 0;
if (t == NULL)
return -1;
if (o & ROTATESPRITE_MAX)
if (!(o & ROTATESPRITE_FULL16))
{
widthx = 320<<16;
shift = 0;
x <<= 16;
y <<= 16;
}
centre = (x == (widthx>>1));
if (centre)
origy = y;
if (x == (widthx>>1)) // center
{
const char *oldt = t;
int32_t newx = 0;
@ -343,7 +343,7 @@ int32_t G_PrintGameText(int32_t f, int32_t tile, int32_t x, int32_t y, const
if (*t == 32)
{
newx += ((((f & 8) ? 8 : 5) - squishtext) * z)>>16;
newx += ((((f & 8) ? 8 : 5) - squishtext) * z);
continue;
}
@ -361,11 +361,11 @@ int32_t G_PrintGameText(int32_t f, int32_t tile, int32_t x, int32_t y, const
if (ac < tile || ac > (tile + 93))
break;
i = ((((f & 8) ? 8 : tilesizx[ac]) - squishtext) * z)>>16;
i = ((((f & 8) ? 8 : tilesizx[ac]) - squishtext) * z);
newx += i;
if (*t >= '0' && *t <= '9')
newx -= i - ((8 * z)>>16);
newx -= i - ((8 * z));
}
while (*(++t));
@ -373,19 +373,16 @@ int32_t G_PrintGameText(int32_t f, int32_t tile, int32_t x, int32_t y, const
x = (f & 4) ?
(xres>>1)-textsc(newx>>1) :
(widthx>>1)-((o & ROTATESPRITE_MAX)?newx<<15:newx>>1);
(widthx>>1)-(newx>>1);
}
ox = x;
oy = y;
do
{
int32_t i;
if (*t == 32)
{
x += ((((f & 8) ? 8 : 5) - squishtext) * z)>>16;
j += ((((f & 8) ? 8 : 5) - squishtext) * z);
continue;
}
@ -413,43 +410,37 @@ int32_t G_PrintGameText(int32_t f, int32_t tile, int32_t x, int32_t y, const
if (ac < tile || ac > (tile + 93))
break;
if (o&ROTATESPRITE_MAX)
{
ox = x += (x-ox)<<16;
oy = y += (y-oy)<<16;
}
if (f&4)
{
rotatesprite(textsc(x<<shift), (origy<<shift)+textsc((y-origy)<<shift), textsc(z),
rotatesprite(textsc(x+j), (origy)+textsc((y-origy)), textsc(z),
0,ac,s,p,(8|16|(o&1)|(o&32)),x1,y1,x2,y2);
}
else
{
const int32_t orient = (f&1) ? (8|16|(o&1)|(o&32)) : (2|o);
rotatesprite(x<<shift, y<<shift, z,
rotatesprite(x+j, y, z,
0,ac,s,p,orient,x1,y1,x2,y2);
}
i = (f & 8) ?
((8 - squishtext) * z)>>16 :
((tilesizx[ac] - squishtext) * z)>>16;
x += i;
((8 - squishtext) * z):
((tilesizx[ac] - squishtext) * z);
j += i;
if (*t >= '0' && *t <= '9')
x -= i-((8*z)>>16);
j -= i-((8*z));
// wrapping long strings doesn't work for precise coordinates due to overflow
// XXX: above comment obsolete?
if ((o&ROTATESPRITE_MAX) == 0)
if (!(o&ROTATESPRITE_FULL16))
{
if (((f&4) ? textsc(x) : x) > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET))
x = origx, y += z>>13;
if (((f&4) ? textsc(x+j) : (x+j)) > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET)<<16)
j = 0, y += z<<3; // z == 65536 --> 8<<16
}
}
while (*(++t));
return x;
return origx + ((o & ROTATESPRITE_FULL16) ? j : (j>>16));
}
int32_t G_GameTextLen(int32_t x,const char *t)
@ -490,7 +481,7 @@ static int32_t minitext_yofs = 0;
static int32_t minitext_lowercase = 0;
int32_t minitext_(int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t sb)
{
int32_t ac;
int32_t ac, j = 0;
char ch, cmode;
cmode = (sb&ROTATESPRITE_MAX)!=0;
@ -502,6 +493,12 @@ int32_t minitext_(int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t
return 0;
}
if (!(sb&ROTATESPRITE_FULL16))
{
x<<=16;
y<<=16;
}
do
{
if (*t == '^' && isdigit(*(t+1)))
@ -527,19 +524,19 @@ int32_t minitext_(int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t
if (ch == 32)
{
x+=5;
j+=5;
continue;
}
else ac = ch - '!' + MINIFONT;
if (cmode) rotatesprite_fs(sbarx(x),minitext_yofs+sbary(y),sbarsc(65536L),0,ac,s,p,sb);
else rotatesprite_fs(x<<16,y<<16,65536L,0,ac,s,p,sb);
x += (tilesizx[ac] > 0 ? tilesizx[ac] : 3) + 1;
if (cmode) rotatesprite_fs(sbarx(x+j),minitext_yofs+sbary(y),sbarsc(65536L),0,ac,s,p,sb);
else rotatesprite_fs(x+(j<<16),y,65536L,0,ac,s,p,sb);
j += (tilesizx[ac] > 0 ? tilesizx[ac] : 3) + 1;
}
while (*(++t));
return (x);
return x+(j<<((sb&ROTATESPRITE_FULL16)?16:0));
}
void G_AddUserQuote(const char *daquote)
@ -711,7 +708,13 @@ void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum,
if (orientation&4)
a = 1024;
rotatesprite_win(x<<16, y<<16, zoom,a,tilenum,shade,p,2|orientation);
if (!(orientation&ROTATESPRITE_FULL16))
{
x<<=16;
y<<=16;
}
rotatesprite_win(x,y,zoom,a,tilenum,shade,p,2|orientation);
}
#if !defined LUNATIC
@ -993,24 +996,24 @@ void G_DrawTXDigiNumZ(int32_t starttile, int32_t x,int32_t y,int32_t n,int32_t s
{
int32_t i, j = 0, k, p, c;
char b[12];
const int32_t shift = 16;
const int32_t shift = (cs&ROTATESPRITE_FULL16)?0:16;
i = Bsprintf(b,"%d",n);
// center the number string
for (k=i-1; k>=0; k--)
{
p = starttile + b[k]-'0';
j += ((1+tilesizx[p])*z)>>16;
j += ((1+tilesizx[p])*z);
}
if (cs&ROTATESPRITE_MAX) j<<=16;
c = x-(j>>1);
c = (x<<shift)-(j>>1);
j = 0;
for (k=0; k<i; k++)
{
p = starttile + b[k]-'0';
rotatesprite((c+j)<<shift,y<<shift,z,0,p,s,pal,2|cs,x1,y1,x2,y2);
j += (((1+tilesizx[p])*z)>>((cs&ROTATESPRITE_MAX)?0:16));
rotatesprite(c+j,y<<shift,z,0,p,s,pal,2|cs,x1,y1,x2,y2);
j += ((1+tilesizx[p])*z);
}
}

View file

@ -2603,7 +2603,7 @@ nullquote:
int32_t x1=Gv_GetVarX(*insptr++), y1=Gv_GetVarX(*insptr++);
int32_t x2=Gv_GetVarX(*insptr++), y2=Gv_GetVarX(*insptr++);
if (tw == CON_ROTATESPRITE)
if (tw == CON_ROTATESPRITE && !(orientation&ROTATESPRITE_FULL16))
{
x<<=16;
y<<=16;

View file

@ -282,7 +282,7 @@ end
function rotatesprite(x, y, zoom, ang, tilenum, shade, pal, orientation,
cx1, cy1, cx2, cy2)
check_tile_idx(tilenum)
orientation = bit.band(orientation, 2047) -- ROTATESPRITE_MAX-1
orientation = bit.band(orientation, 4095) -- ROTATESPRITE_MAX-1
-- XXX: This is the same as the check in gameexec.c, but ideally we'd want
-- rotatesprite to accept all coordinates and simply draw nothing if they
@ -291,9 +291,14 @@ function rotatesprite(x, y, zoom, ang, tilenum, shade, pal, orientation,
error(format("invalid coordinates (%.03f, %.03f)", x, y), 2)
end
if (bit.band(orientation, 2048) ~= 2048) then -- ROTATESPRITE_FULL16
x = 65536*x
y = 65536*y
end
-- TODO: check that it works correctly with all coordinates, also if one
-- border is outside the screen etc...
ffiC.rotatesprite(65536*x, 65536*y, zoom, ang, tilenum, shade, pal, bit.bor(2,orientation),
ffiC.rotatesprite(x, y, zoom, ang, tilenum, shade, pal, bit.bor(2,orientation),
cx1, cy1, cx2, cy2)
end
@ -738,7 +743,7 @@ function _gametext(tilenum, x, y, qnum, shade, pal, orientation,
local cstr = bcheck.quote_idx(qnum)
orientation = bit.band(orientation, 2047) -- ROTATESPRITE_MAX-1
orientation = bit.band(orientation, 4095) -- ROTATESPRITE_MAX-1
ffiC.G_PrintGameText(0, tilenum, bit.arshift(x,1), y, cstr, shade, pal,
orientation, cx1, cy1, cx2, cy2, zoom)
end