mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-30 13:10:55 +00:00
Merge branch 'accurate-papersprites' into 'master'
Accurate papersprite projection See merge request STJr/SRB2!657
This commit is contained in:
commit
dc151fc7a4
2 changed files with 92 additions and 79 deletions
168
src/r_things.c
168
src/r_things.c
|
@ -740,9 +740,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
||||||
static void R_DrawVisSprite(vissprite_t *vis)
|
static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
{
|
{
|
||||||
column_t *column;
|
column_t *column;
|
||||||
#ifdef RANGECHECK
|
|
||||||
INT32 texturecolumn;
|
INT32 texturecolumn;
|
||||||
#endif
|
|
||||||
fixed_t frac;
|
fixed_t frac;
|
||||||
patch_t *patch = vis->patch;
|
patch_t *patch = vis->patch;
|
||||||
fixed_t this_scale = vis->mobj->scale;
|
fixed_t this_scale = vis->mobj->scale;
|
||||||
|
@ -890,28 +888,51 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
if (vis->x2 >= vid.width)
|
if (vis->x2 >= vid.width)
|
||||||
vis->x2 = vid.width-1;
|
vis->x2 = vid.width-1;
|
||||||
|
|
||||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
|
||||||
|
if (vis->scalestep)
|
||||||
{
|
{
|
||||||
#ifdef RANGECHECK
|
// Papersprite drawing loop
|
||||||
|
|
||||||
texturecolumn = frac>>FRACBITS;
|
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
|
||||||
|
|
||||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
|
||||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
|
||||||
#else
|
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
|
||||||
#endif
|
|
||||||
if (vis->scalestep)
|
|
||||||
{
|
{
|
||||||
|
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||||
|
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
|
||||||
|
|
||||||
|
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (vis->xiscale < 0) // Flipped sprite
|
||||||
|
texturecolumn = SHORT(patch->width) - 1 - texturecolumn;
|
||||||
|
|
||||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||||
|
|
||||||
|
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||||
|
|
||||||
|
if (vis->cut & SC_VFLIP)
|
||||||
|
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||||
|
else
|
||||||
|
R_DrawMaskedColumn(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Non-paper drawing loop
|
||||||
|
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||||
|
{
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
texturecolumn = frac>>FRACBITS;
|
||||||
|
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||||
|
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||||
|
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||||
|
#else
|
||||||
|
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||||
|
#endif
|
||||||
|
if (vis->cut & SC_VFLIP)
|
||||||
|
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||||
|
else
|
||||||
|
R_DrawMaskedColumn(column);
|
||||||
}
|
}
|
||||||
if (vis->cut & SC_VFLIP)
|
|
||||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
|
||||||
else
|
|
||||||
R_DrawMaskedColumn(column);
|
|
||||||
spryscale += vis->scalestep;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
colfunc = colfuncs[BASEDRAWFUNC];
|
colfunc = colfuncs[BASEDRAWFUNC];
|
||||||
|
@ -1070,8 +1091,6 @@ static void R_SplitSprite(vissprite_t *sprite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define PROPERPAPER // This was reverted less than 7 hours before 2.2's release because of very strange, frequent crashes.
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_ProjectSprite
|
// R_ProjectSprite
|
||||||
// Generates a vissprite for a thing
|
// Generates a vissprite for a thing
|
||||||
|
@ -1108,7 +1127,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
fixed_t iscale;
|
fixed_t iscale;
|
||||||
fixed_t scalestep;
|
fixed_t scalestep;
|
||||||
fixed_t offset, offset2;
|
fixed_t offset, offset2;
|
||||||
|
|
||||||
boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
|
boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
|
||||||
|
fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0;
|
||||||
|
|
||||||
INT32 dispoffset = thing->info->dispoffset;
|
INT32 dispoffset = thing->info->dispoffset;
|
||||||
|
|
||||||
|
@ -1127,10 +1148,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS;
|
UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PROPERPAPER
|
|
||||||
fixed_t ang_scale = FRACUNIT;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// transform the origin point
|
// transform the origin point
|
||||||
tr_x = thing->x - viewx;
|
tr_x = thing->x - viewx;
|
||||||
tr_y = thing->y - viewy;
|
tr_y = thing->y - viewy;
|
||||||
|
@ -1141,7 +1158,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
tz = gxt-gyt;
|
tz = gxt-gyt;
|
||||||
|
|
||||||
// thing is behind view plane?
|
// thing is behind view plane?
|
||||||
if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
|
if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gxt = -FixedMul(tr_x, viewsin);
|
gxt = -FixedMul(tr_x, viewsin);
|
||||||
|
@ -1149,7 +1166,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
tx = -(gyt + gxt);
|
tx = -(gyt + gxt);
|
||||||
|
|
||||||
// too far off the side?
|
// too far off the side?
|
||||||
if (abs(tx) > tz<<2)
|
if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// aspect ratio stuff
|
// aspect ratio stuff
|
||||||
|
@ -1213,13 +1230,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||||
{
|
|
||||||
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
|
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
|
||||||
#ifndef PROPERPAPER
|
|
||||||
if (papersprite)
|
|
||||||
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sprframe->rotate == SRF_SINGLE)
|
if (sprframe->rotate == SRF_SINGLE)
|
||||||
{
|
{
|
||||||
|
@ -1280,31 +1291,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
else
|
else
|
||||||
offset = -spr_offset;
|
offset = -spr_offset;
|
||||||
offset = FixedMul(offset, this_scale);
|
offset = FixedMul(offset, this_scale);
|
||||||
#ifndef PROPERPAPER
|
|
||||||
tx += FixedMul(offset, ang_scale);
|
|
||||||
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
|
|
||||||
|
|
||||||
// off the right side?
|
|
||||||
if (x1 > viewwidth)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
offset2 = FixedMul(spr_width, this_scale);
|
offset2 = FixedMul(spr_width, this_scale);
|
||||||
#ifndef PROPERPAPER
|
|
||||||
tx += FixedMul(offset2, ang_scale);
|
|
||||||
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
|
|
||||||
|
|
||||||
// off the left side
|
|
||||||
if (x2 < 0)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (papersprite)
|
if (papersprite)
|
||||||
{
|
{
|
||||||
fixed_t
|
fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2;
|
||||||
#ifdef PROPERPAPER
|
|
||||||
xscale2,
|
|
||||||
#endif
|
|
||||||
yscale2, cosmul, sinmul, tz2;
|
|
||||||
INT32 range;
|
INT32 range;
|
||||||
|
|
||||||
if (ang >= ANGLE_180)
|
if (ang >= ANGLE_180)
|
||||||
|
@ -1322,19 +1313,23 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
gyt = -FixedMul(tr_y, viewsin);
|
gyt = -FixedMul(tr_y, viewsin);
|
||||||
tz = gxt-gyt;
|
tz = gxt-gyt;
|
||||||
yscale = FixedDiv(projectiony, tz);
|
yscale = FixedDiv(projectiony, tz);
|
||||||
if (yscale < 64) return; // Fix some funky visuals
|
//if (yscale < 64) return; // Fix some funky visuals
|
||||||
|
|
||||||
#ifdef PROPERPAPER
|
|
||||||
gxt = -FixedMul(tr_x, viewsin);
|
gxt = -FixedMul(tr_x, viewsin);
|
||||||
gyt = FixedMul(tr_y, viewcos);
|
gyt = FixedMul(tr_y, viewcos);
|
||||||
tx = -(gyt + gxt);
|
tx = -(gyt + gxt);
|
||||||
xscale = FixedDiv(projection, tz);
|
xscale = FixedDiv(projection, tz);
|
||||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||||
|
|
||||||
// off the right side?
|
// Get paperoffset (offset) and paperoffset (distance)
|
||||||
if (x1 > viewwidth)
|
paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul);
|
||||||
return;
|
paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul);
|
||||||
#endif
|
if (paperdistance < 0)
|
||||||
|
{
|
||||||
|
paperoffset = -paperoffset;
|
||||||
|
paperdistance = -paperdistance;
|
||||||
|
}
|
||||||
|
centerangle = viewangle - thing->angle;
|
||||||
|
|
||||||
tr_x += FixedMul(offset2, cosmul);
|
tr_x += FixedMul(offset2, cosmul);
|
||||||
tr_y += FixedMul(offset2, sinmul);
|
tr_y += FixedMul(offset2, sinmul);
|
||||||
|
@ -1342,38 +1337,52 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
gyt = -FixedMul(tr_y, viewsin);
|
gyt = -FixedMul(tr_y, viewsin);
|
||||||
tz2 = gxt-gyt;
|
tz2 = gxt-gyt;
|
||||||
yscale2 = FixedDiv(projectiony, tz2);
|
yscale2 = FixedDiv(projectiony, tz2);
|
||||||
if (yscale2 < 64) return; // ditto
|
//if (yscale2 < 64) return; // ditto
|
||||||
|
|
||||||
#ifdef PROPERPAPER
|
|
||||||
gxt = -FixedMul(tr_x, viewsin);
|
gxt = -FixedMul(tr_x, viewsin);
|
||||||
gyt = FixedMul(tr_y, viewcos);
|
gyt = FixedMul(tr_y, viewcos);
|
||||||
tx = -(gyt + gxt);
|
tx2 = -(gyt + gxt);
|
||||||
xscale2 = FixedDiv(projection, tz2);
|
xscale2 = FixedDiv(projection, tz2);
|
||||||
x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--;
|
x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS);
|
||||||
|
|
||||||
|
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Needs partially clipped
|
||||||
|
if (tz < FixedMul(MINZ, this_scale))
|
||||||
|
{
|
||||||
|
fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz);
|
||||||
|
tx += FixedDiv(tx2-tx, div);
|
||||||
|
tz = FixedMul(MINZ, this_scale);
|
||||||
|
yscale = FixedDiv(projectiony, tz);
|
||||||
|
xscale = FixedDiv(projection, tz);
|
||||||
|
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||||
|
}
|
||||||
|
else if (tz2 < FixedMul(MINZ, this_scale))
|
||||||
|
{
|
||||||
|
fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2);
|
||||||
|
tx2 += FixedDiv(tx-tx2, div);
|
||||||
|
tz2 = FixedMul(MINZ, this_scale);
|
||||||
|
yscale2 = FixedDiv(projectiony, tz2);
|
||||||
|
xscale2 = FixedDiv(projection, tz2);
|
||||||
|
x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// off the right side?
|
||||||
|
if (x1 > viewwidth)
|
||||||
|
return;
|
||||||
|
|
||||||
// off the left side
|
// off the left side
|
||||||
if (x2 < 0)
|
if (x2 < 0)
|
||||||
return;
|
return;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((range = x2 - x1) <= 0)
|
if ((range = x2 - x1) <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef PROPERPAPER
|
|
||||||
range++; // fencepost problem
|
range++; // fencepost problem
|
||||||
#endif
|
|
||||||
|
|
||||||
scalestep = (yscale2 - yscale)/range;
|
scalestep = ((yscale2 - yscale)/range) ?: 1;
|
||||||
xscale =
|
xscale = FixedDiv(range<<FRACBITS, abs(offset2));
|
||||||
#ifdef PROPERPAPER
|
|
||||||
FixedDiv(range<<FRACBITS, abs(offset2))+1
|
|
||||||
#else
|
|
||||||
FixedMul(xscale, ang_scale)
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||||
// sortscale = max(yscale, yscale2);
|
// sortscale = max(yscale, yscale2);
|
||||||
|
@ -1383,7 +1392,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
{
|
{
|
||||||
scalestep = 0;
|
scalestep = 0;
|
||||||
yscale = sortscale;
|
yscale = sortscale;
|
||||||
#ifdef PROPERPAPER
|
|
||||||
tx += offset;
|
tx += offset;
|
||||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||||
|
|
||||||
|
@ -1397,7 +1405,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
// off the left side
|
// off the left side
|
||||||
if (x2 < 0)
|
if (x2 < 0)
|
||||||
return;
|
return;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||||
|
@ -1518,6 +1525,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
vis->pzt = vis->pz + vis->thingheight;
|
vis->pzt = vis->pz + vis->thingheight;
|
||||||
vis->texturemid = vis->gzt - viewz;
|
vis->texturemid = vis->gzt - viewz;
|
||||||
vis->scalestep = scalestep;
|
vis->scalestep = scalestep;
|
||||||
|
vis->paperoffset = paperoffset;
|
||||||
|
vis->paperdistance = paperdistance;
|
||||||
|
vis->centerangle = centerangle;
|
||||||
|
|
||||||
vis->mobj = thing; // Easy access! Tails 06-07-2002
|
vis->mobj = thing; // Easy access! Tails 06-07-2002
|
||||||
|
|
||||||
|
|
|
@ -181,8 +181,11 @@ typedef struct vissprite_s
|
||||||
fixed_t startfrac; // horizontal position of x1
|
fixed_t startfrac; // horizontal position of x1
|
||||||
fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
|
fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
|
||||||
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
||||||
|
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
|
||||||
fixed_t xiscale; // negative if flipped
|
fixed_t xiscale; // negative if flipped
|
||||||
|
|
||||||
|
angle_t centerangle; // for paper sprites
|
||||||
|
|
||||||
fixed_t texturemid;
|
fixed_t texturemid;
|
||||||
patch_t *patch;
|
patch_t *patch;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue