mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	Merge branch 'accurate-papersprites' into 'master'
Accurate papersprite projection See merge request STJr/SRB2!657
This commit is contained in:
		
						commit
						a77acb349a
					
				
					 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)
 | 
			
		||||
{
 | 
			
		||||
	column_t *column;
 | 
			
		||||
#ifdef RANGECHECK
 | 
			
		||||
	INT32 texturecolumn;
 | 
			
		||||
#endif
 | 
			
		||||
	fixed_t frac;
 | 
			
		||||
	patch_t *patch = vis->patch;
 | 
			
		||||
	fixed_t this_scale = vis->mobj->scale;
 | 
			
		||||
| 
						 | 
				
			
			@ -890,28 +888,51 @@ static void R_DrawVisSprite(vissprite_t *vis)
 | 
			
		|||
	if (vis->x2 >= vid.width)
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
		for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += 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));
 | 
			
		||||
			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];
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
// Generates a vissprite for a thing
 | 
			
		||||
| 
						 | 
				
			
			@ -1108,7 +1127,9 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
	fixed_t iscale;
 | 
			
		||||
	fixed_t scalestep;
 | 
			
		||||
	fixed_t offset, offset2;
 | 
			
		||||
 | 
			
		||||
	boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
 | 
			
		||||
	fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0;
 | 
			
		||||
 | 
			
		||||
	INT32 dispoffset = thing->info->dispoffset;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1127,10 +1148,6 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
	UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef PROPERPAPER
 | 
			
		||||
	fixed_t ang_scale = FRACUNIT;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// transform the origin point
 | 
			
		||||
	tr_x = thing->x - viewx;
 | 
			
		||||
	tr_y = thing->y - viewy;
 | 
			
		||||
| 
						 | 
				
			
			@ -1141,7 +1158,7 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
	tz = gxt-gyt;
 | 
			
		||||
 | 
			
		||||
	// 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;
 | 
			
		||||
 | 
			
		||||
	gxt = -FixedMul(tr_x, viewsin);
 | 
			
		||||
| 
						 | 
				
			
			@ -1149,7 +1166,7 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
	tx = -(gyt + gxt);
 | 
			
		||||
 | 
			
		||||
	// too far off the side?
 | 
			
		||||
	if (abs(tx) > tz<<2)
 | 
			
		||||
	if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	// aspect ratio stuff
 | 
			
		||||
| 
						 | 
				
			
			@ -1213,13 +1230,7 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
	if (sprframe->rotate != SRF_SINGLE || papersprite)
 | 
			
		||||
	{
 | 
			
		||||
		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)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -1280,31 +1291,11 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
	else
 | 
			
		||||
		offset = -spr_offset;
 | 
			
		||||
	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);
 | 
			
		||||
#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)
 | 
			
		||||
	{
 | 
			
		||||
		fixed_t
 | 
			
		||||
#ifdef PROPERPAPER
 | 
			
		||||
			xscale2,
 | 
			
		||||
#endif
 | 
			
		||||
					yscale2, cosmul, sinmul, tz2;
 | 
			
		||||
		fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2;
 | 
			
		||||
		INT32 range;
 | 
			
		||||
 | 
			
		||||
		if (ang >= ANGLE_180)
 | 
			
		||||
| 
						 | 
				
			
			@ -1322,19 +1313,23 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
		gyt = -FixedMul(tr_y, viewsin);
 | 
			
		||||
		tz = gxt-gyt;
 | 
			
		||||
		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);
 | 
			
		||||
		gyt = FixedMul(tr_y, viewcos);
 | 
			
		||||
		tx = -(gyt + gxt);
 | 
			
		||||
		xscale = FixedDiv(projection, tz);
 | 
			
		||||
		x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
 | 
			
		||||
 | 
			
		||||
		// off the right side?
 | 
			
		||||
		if (x1 > viewwidth)
 | 
			
		||||
			return;
 | 
			
		||||
#endif
 | 
			
		||||
		// Get paperoffset (offset) and paperoffset (distance)
 | 
			
		||||
		paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul);
 | 
			
		||||
		paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul);
 | 
			
		||||
		if (paperdistance < 0)
 | 
			
		||||
		{
 | 
			
		||||
			paperoffset = -paperoffset;
 | 
			
		||||
			paperdistance = -paperdistance;
 | 
			
		||||
		}
 | 
			
		||||
		centerangle = viewangle - thing->angle;
 | 
			
		||||
 | 
			
		||||
		tr_x += FixedMul(offset2, cosmul);
 | 
			
		||||
		tr_y += FixedMul(offset2, sinmul);
 | 
			
		||||
| 
						 | 
				
			
			@ -1342,38 +1337,52 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
		gyt = -FixedMul(tr_y, viewsin);
 | 
			
		||||
		tz2 = gxt-gyt;
 | 
			
		||||
		yscale2 = FixedDiv(projectiony, tz2);
 | 
			
		||||
		if (yscale2 < 64) return; // ditto
 | 
			
		||||
		//if (yscale2 < 64) return; // ditto
 | 
			
		||||
 | 
			
		||||
#ifdef PROPERPAPER
 | 
			
		||||
		gxt = -FixedMul(tr_x, viewsin);
 | 
			
		||||
		gyt = FixedMul(tr_y, viewcos);
 | 
			
		||||
		tx = -(gyt + gxt);
 | 
			
		||||
		tx2 = -(gyt + gxt);
 | 
			
		||||
		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
 | 
			
		||||
		if (x2 < 0)
 | 
			
		||||
			return;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		if ((range = x2 - x1) <= 0)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
#ifdef PROPERPAPER
 | 
			
		||||
		range++; // fencepost problem
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		scalestep = (yscale2 - yscale)/range;
 | 
			
		||||
		xscale =
 | 
			
		||||
#ifdef PROPERPAPER
 | 
			
		||||
		FixedDiv(range<<FRACBITS, abs(offset2))+1
 | 
			
		||||
#else
 | 
			
		||||
		FixedMul(xscale, ang_scale)
 | 
			
		||||
#endif
 | 
			
		||||
		;
 | 
			
		||||
		scalestep = ((yscale2 - yscale)/range) ?: 1;
 | 
			
		||||
		xscale = FixedDiv(range<<FRACBITS, abs(offset2));
 | 
			
		||||
 | 
			
		||||
		// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
 | 
			
		||||
		// sortscale = max(yscale, yscale2);
 | 
			
		||||
| 
						 | 
				
			
			@ -1383,7 +1392,6 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
	{
 | 
			
		||||
		scalestep = 0;
 | 
			
		||||
		yscale = sortscale;
 | 
			
		||||
#ifdef PROPERPAPER
 | 
			
		||||
		tx += offset;
 | 
			
		||||
		x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1397,7 +1405,6 @@ static void R_ProjectSprite(mobj_t *thing)
 | 
			
		|||
		// off the left side
 | 
			
		||||
		if (x2 < 0)
 | 
			
		||||
			return;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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->texturemid = vis->gzt - viewz;
 | 
			
		||||
	vis->scalestep = scalestep;
 | 
			
		||||
	vis->paperoffset = paperoffset;
 | 
			
		||||
	vis->paperdistance = paperdistance;
 | 
			
		||||
	vis->centerangle = centerangle;
 | 
			
		||||
 | 
			
		||||
	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 scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
	angle_t centerangle; // for paper sprites
 | 
			
		||||
 | 
			
		||||
	fixed_t texturemid;
 | 
			
		||||
	patch_t *patch;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue