shithub: hexen

Download patch

ref: ea9c413dbbeb6dcf9efcc6a00329e4049bd538a9
parent: 574a1f3101d3a78ef86ede3ae389b18dbe468dce
author: Jacob Moody <[email protected]>
date: Sat Feb 4 19:32:38 EST 2023

progress torwards correct demos

Ordering matters a lot for our P_Random()
function with global side effects.

First issue is with code that uses it like this:

P_Random() - P_Random()

compared to gcc this had two issues, the ordering
was different and becuase this function returned a
uchar we were not allowing it to become negative.

So we steal P_Random2() from our doom, and add our
own P_Random3 to cover the large amount of P_Random() - 128
that would also have this sign issue.

The second issue is in how inlined calls are ordered example:

fn(P_Rand() + 1, P_Random() + 2, P_Random() + 3);

we order how you read it, left to right. gcc does it right to left.
So in relevant places we use locals and reverse the ordering of how
these are called.

This fixes these issues for callers of P_SpawnMobj, which seemed
to be a decent chunk of the offenders.

This has impacted demos, they are arguably 'closer' to accurate.
demo1 still goes out of sync due to a hit connecting in our demo
playback but not in the original. This causes/misses a hitsplat and
that throws off the entire prng. Likely due to similar issues in the
enemy movement logic.

--- a/a_action.c
+++ b/a_action.c
@@ -113,25 +113,6 @@
 //
 //--------------------------------------------------------------------------
 
-//==========================================================================
-//
-// A_DripBlood
-//
-//==========================================================================
-
-/*
-void A_DripBlood(mobj_t *actor)
-{
-	mobj_t *mo;
-
-	mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<11),
-		actor->y+((P_Random()-P_Random())<<11), actor->z, MT_BLOOD);
-	mo->momx = (P_Random()-P_Random())<<10;
-	mo->momy = (P_Random()-P_Random())<<10;
-	mo->flags2 |= MF2_LOGRAV;
-}
-*/
-
 //============================================================================
 //
 // A_PotteryExplode
@@ -150,8 +131,8 @@
 		if (mo)
 		{
 			mo->momz = ((P_Random()&7)+5)*(3*FRACUNIT/4);
-			mo->momx = (P_Random()-P_Random())<<(FRACBITS-6);
-			mo->momy = (P_Random()-P_Random())<<(FRACBITS-6);
+			mo->momx = (P_Random2())<<(FRACBITS-6);
+			mo->momy = (P_Random2())<<(FRACBITS-6);
 		}
 	}
 	S_StartSound(mo, SFX_POTTERY_EXPLODE);
@@ -255,8 +236,8 @@
 		if (mo)
 		{
 			mo->momz = ((P_Random()&7)+5)*(3*FRACUNIT/4);
-			mo->momx = (P_Random()-P_Random())<<(FRACBITS-6);
-			mo->momy = (P_Random()-P_Random())<<(FRACBITS-6);
+			mo->momx = (P_Random2())<<(FRACBITS-6);
+			mo->momy = (P_Random2())<<(FRACBITS-6);
 		}
 	}
 	// Spawn a skull
@@ -265,8 +246,8 @@
 	if (mo)
 	{
 		mo->momz = ((P_Random()&7) + 5) * (3*FRACUNIT/4);
-		mo->momx = (P_Random()-P_Random())<<(FRACBITS-6);
-		mo->momy = (P_Random()-P_Random())<<(FRACBITS-6);
+		mo->momx = (P_Random2())<<(FRACBITS-6);
+		mo->momy = (P_Random2())<<(FRACBITS-6);
 		S_StartSound(mo, SFX_FIRED_DEATH);
 	}
 	P_RemoveMobj(actor);
@@ -283,12 +264,26 @@
 	mobj_t *mo;
 	int i;
 
+	int a, b, c, d;
+
 	for (i = (P_Random()&3)+1; i; i--)
 	{
-		mo = P_SpawnMobj(actor->x + ((P_Random()-P_Random())<<14),
-				 actor->y + ((P_Random()-P_Random())<<14),
-				 actor->z + (P_Random()<<14),
-				 MT_LEAF1 + (P_Random()&1));
+		//print("LEAF\n");
+		/* a = ((P_Random2())<<14);
+		b = ((P_Random2())<<14);
+		c = (P_Random()<<14); */
+
+		d = (P_Random()&1);
+		c = (P_Random()<<14);
+		b = ((P_Random2())<<14);
+		a = ((P_Random2())<<14);
+
+		//print("%d %d %d %d\n", a, b, c, d);
+		//print("%d %d %d\n", actor->x + a, actor->y + b, actor->z + c);
+		mo = P_SpawnMobj(actor->x + a,
+				 actor->y + b,
+				 actor->z + c,
+				 MT_LEAF1 + d);
 		if (mo)
 		{
 			P_ThrustMobj(mo, actor->angle, (P_Random()<<9)+3*FRACUNIT);
@@ -1016,8 +1011,8 @@
 	angle = P_Random()<<5;		// <<24 >>19
 	x = actor->x + FixedMul(radius,finecosine[angle]);
 	y = actor->y + FixedMul(radius,finesine[angle]);
-//	x = actor->x + ((P_Random()-P_Random())%radius)<<FRACBITS;
-//	y = actor->y + ((P_Random()-P_Random()<<FRACBITS)%radius);
+//	x = actor->x + ((P_Random2())%radius)<<FRACBITS;
+//	y = actor->y + ((P_Random2()<<FRACBITS)%radius);
 	z = actor->z + (P_Random()<<9) + FRACUNIT;
 	switch (P_Random() % 6)
 	{
@@ -1139,18 +1134,23 @@
 	mobj_t *mo;
 	int i;
 
+	int a, b, c, d;
+
 	mo = nil;
 	for (i = 0; i < 10; i++)
 	{
-		mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), 
-			actor->y + ((P_Random()-128)<<12), 
-			actor->z + (P_Random()*actor->height/256), MT_ZARMORCHUNK);
+		c = (P_Random()*actor->height/256);
+		b = ((P_Random3())<<12);
+		a = ((P_Random3())<<12);
+		mo = P_SpawnMobj(actor->x+ a,
+			actor->y + b, 
+			actor->z + c, MT_ZARMORCHUNK);
 		P_SetMobjState(mo, mo->info->spawnstate + i);
 		if (mo)
 		{
 			mo->momz = ((P_Random()&7)+5)*FRACUNIT;
-			mo->momx = (P_Random()-P_Random())<<(FRACBITS-6);
-			mo->momy = (P_Random()-P_Random())<<(FRACBITS-6);
+			mo->momx = (P_Random2())<<(FRACBITS-6);
+			mo->momy = (P_Random2())<<(FRACBITS-6);
 		}
 	}
 	if (actor->args[0])
--- a/h2def.h
+++ b/h2def.h
@@ -1481,6 +1481,8 @@
 /* returns a number from 0 to 255 */
 
 unsigned char P_Random(void);
+int P_Random2 (void);	/* P_Random() - P_Random() */
+int P_Random3 (void);	/* P_Random() - 128 */
 /* as M_Random, but used only by the play simulation */
 
 void M_ClearRandom (void);
--- a/m_misc.c
+++ b/m_misc.c
@@ -161,6 +161,23 @@
 	return rndtable[prndindex];
 }
 
+int P_Random2 (void)
+{
+	int tmp, tmp2;
+	tmp = P_Random();
+	tmp2 = P_Random();
+	return tmp - tmp2;
+}
+
+int P_Random3 (void)
+{
+	int tmp;
+
+	tmp = P_Random();
+	tmp = tmp - 128;
+	return tmp;
+}
+
 int M_Random (void)
 {
 	rndindex = (rndindex + 1) & 0xff;
--- a/p_enemy.c
+++ b/p_enemy.c
@@ -793,7 +793,7 @@
 	actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y);
 	if (actor->target->flags & MF_SHADOW)
 	{ // Target is a ghost
-		actor->angle += (P_Random() - P_Random()) << 21;
+		actor->angle += (P_Random2()) << 21;
 	}
 }
 
@@ -1445,10 +1445,13 @@
 void A_MntrFloorFire(mobj_t *actor)
 {
 	mobj_t *mo;
+	int a, b;
 
 	actor->z = actor->floorz;
-	mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 10),
-			 actor->y + ((P_Random() - P_Random()) << 10), ONFLOORZ, MT_MNTRFX3);
+	b = ((P_Random2()) << 10);
+	a = ((P_Random2()) << 10);
+	mo = P_SpawnMobj(actor->x + a,
+			 actor->y + b, ONFLOORZ, MT_MNTRFX3);
 	mo->target = actor->target;
 	mo->momx = 1; // Force block checking
 	P_CheckMissileSpawn(mo);
@@ -1559,8 +1562,8 @@
 		return;
 	}
 	mo = P_SpawnMobj(source->x, source->y, source->z + (source->height>>1), type);
-	mo->momx = (P_Random() - P_Random()) << 8;
-	mo->momy = (P_Random() - P_Random()) << 8;
+	mo->momx = (P_Random2()) << 8;
+	mo->momy = (P_Random2()) << 8;
 	mo->momz = FRACUNIT*5 + (P_Random() << 10);
 	mo->flags2 |= MF2_DROPPED;
 	mo->health = special;
@@ -1734,8 +1737,8 @@
 	actor->flags &= ~MF_SOLID;
 	mo = P_SpawnMobj(actor->x, actor->y, actor->z + 48*FRACUNIT, MT_BLOODYSKULL);
 	//mo->target = actor;
-	mo->momx = (P_Random() - P_Random()) << 9;
-	mo->momy = (P_Random() - P_Random()) << 9;
+	mo->momx = (P_Random2()) << 9;
+	mo->momy = (P_Random2()) << 9;
 	mo->momz = FRACUNIT*2 + (P_Random() << 6);
 	// Attach player mobj to bloody skull
 	player = actor->player;
@@ -2366,32 +2369,39 @@
 void A_SerpentSpawnGibs(mobj_t *actor)
 {
 	mobj_t *mo;
+	int a, b;
 
-	mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
-			 actor->y + ((P_Random() - 128) << 12),
+	b = ((P_Random3()) << 12);
+	a = ((P_Random3()) << 12);
+	mo = P_SpawnMobj(actor->x + a,
+			 actor->y + b,
 			 actor->floorz + FRACUNIT, MT_SERPENT_GIB1);
 	if (mo)
 	{
-		mo->momx = (P_Random() - 128) << 6;
-		mo->momy = (P_Random() - 128) << 6;
+		mo->momx = (P_Random3()) << 6;
+		mo->momy = (P_Random3()) << 6;
 		mo->floorclip = 6*FRACUNIT;
 	}
-	mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
-			 actor->y + ((P_Random() - 128) << 12),
+	b = ((P_Random3()) << 12);
+	a = ((P_Random3()) << 12);
+	mo = P_SpawnMobj(actor->x + a,
+			 actor->y + b,
 			 actor->floorz + FRACUNIT, MT_SERPENT_GIB2);
 	if (mo)
 	{
-		mo->momx = (P_Random() - 128) << 6;
-		mo->momy = (P_Random() - 128) << 6;
+		mo->momx = (P_Random3()) << 6;
+		mo->momy = (P_Random3()) << 6;
 		mo->floorclip = 6*FRACUNIT;
 	}
-	mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
-			 actor->y + ((P_Random() - 128) << 12),
+	b = ((P_Random3()) << 12);
+	a = ((P_Random3()) << 12);
+	mo = P_SpawnMobj(actor->x + a,
+			 actor->y + b,
 			 actor->floorz + FRACUNIT, MT_SERPENT_GIB3);
 	if (mo)
 	{
-		mo->momx = (P_Random() - 128) << 6;
-		mo->momy = (P_Random() - 128) << 6;
+		mo->momx = (P_Random3()) << 6;
+		mo->momy = (P_Random3()) << 6;
 		mo->floorclip = 6*FRACUNIT;
 	}
 }
@@ -2502,9 +2512,9 @@
 	{
 		angle = actor->angle + ANG90;
 		mo->momz = FRACUNIT*8 + (P_Random() << 10);
-		mo->momx = FixedMul(((P_Random() - 128) << 11) + FRACUNIT,
+		mo->momx = FixedMul(((P_Random3()) << 11) + FRACUNIT,
 				    finecosine[angle >> ANGLETOFINESHIFT]);
-		mo->momy = FixedMul(((P_Random() - 128) << 11) + FRACUNIT,
+		mo->momy = FixedMul(((P_Random3()) << 11) + FRACUNIT,
 				    finesine[angle >> ANGLETOFINESHIFT]);
 		mo->target = actor;
 	}
@@ -2513,9 +2523,9 @@
 	{
 		angle = actor->angle - ANG90;
 		mo->momz = FRACUNIT*8 + (P_Random() << 10);
-		mo->momx = FixedMul(((P_Random() - 128) << 11) + FRACUNIT,
+		mo->momx = FixedMul(((P_Random3()) << 11) + FRACUNIT,
 				    finecosine[angle >> ANGLETOFINESHIFT]);
-		mo->momy = FixedMul(((P_Random() - 128) << 11) + FRACUNIT,
+		mo->momy = FixedMul(((P_Random3()) << 11) + FRACUNIT,
 				    finesine[angle>>ANGLETOFINESHIFT]);
 		mo->target = actor;
 	}
@@ -2733,6 +2743,7 @@
 void A_BishopPainBlur(mobj_t *actor)
 {
 	mobj_t *mo;
+	int a, b, c;
 
 	if (P_Random() < 64)
 	{
@@ -2739,9 +2750,12 @@
 		P_SetMobjState(actor, S_BISHOP_BLUR1);
 		return;
 	}
-	mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 12),
-			 actor->y + ((P_Random() - P_Random()) << 12),
-			 actor->z + ((P_Random() - P_Random()) << 11),
+	c = ((P_Random2()) << 11);
+	b = ((P_Random2()) << 12);
+	a = ((P_Random2()) << 12);
+	mo = P_SpawnMobj(actor->x + a,
+			 actor->y + b,
+			 actor->z + c,
 			 MT_BISHOPPAINBLUR);
 	if (mo)
 	{
@@ -2972,13 +2986,17 @@
 	mobj_t *mo;
 	int i;
 	int delay;
+	int a, b, c;
 
 	delay = 16 + (P_Random() >> 3);
-	for (i = 1 + (P_Random() & 3); i; i--)
+	for (i = 1 + (P_Random() & 3); i > 0; i--)
 	{
-		mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 14),
-				 actor->y + ((P_Random() - 128) << 14),
-				 actor->z + ((P_Random() - 128) << 12),
+		c = ((P_Random3()) << 12);
+		b = ((P_Random3()) << 14);
+		a = ((P_Random3()) << 14);
+		mo = P_SpawnMobj(actor->x + a,
+				 actor->y + b,
+				 actor->z + c,
 				 MT_DRAGON_FX2);
 		if (mo)
 		{
@@ -3358,8 +3376,8 @@
 		mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX3);
 		if (mo)
 		{
-			mo->x += (P_Random() - 128) << 11;
-			mo->y += (P_Random() - 128) << 11;
+			mo->x += (P_Random3()) << 11;
+			mo->y += (P_Random3()) << 11;
 			mo->z += (P_Random() << 10);
 			mo->target = actor;
 		}
@@ -3399,8 +3417,8 @@
 		mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX4);
 		if (mo)
 		{
-			mo->x += (P_Random() - 128) << 12;
-			mo->y += (P_Random() - 128) << 12;
+			mo->x += (P_Random3()) << 12;
+			mo->y += (P_Random3()) << 12;
 			mo->z += (P_Random() << 10);
 			mo->target = actor;
 		}
@@ -3410,8 +3428,8 @@
 		mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX5);
 		if (mo)
 		{
-			mo->x += (P_Random() - 128) << 11;
-			mo->y += (P_Random() - 128) << 11;
+			mo->x += (P_Random3()) << 11;
+			mo->y += (P_Random3()) << 11;
 			mo->z += (P_Random() << 10);
 			mo->target = actor;
 		}
@@ -3458,8 +3476,8 @@
 	mo = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height>>1), MT_ETTIN_MACE);
 	if (mo)
 	{
-		mo->momx = (P_Random() - 128) << 11;
-		mo->momy = (P_Random() - 128) << 11;
+		mo->momx = (P_Random3()) << 11;
+		mo->momy = (P_Random3()) << 11;
 		mo->momz = FRACUNIT*10 + (P_Random() << 10);
 		mo->target = actor;
 	}
@@ -3498,15 +3516,15 @@
 		break;
 	}
 
-	x = actor->x + ((P_Random() - 128) << 12);
-	y = actor->y + ((P_Random() - 128) << 12);
+	x = actor->x + ((P_Random3()) << 12);
+	y = actor->y + ((P_Random3()) << 12);
 	z = actor->z + ((P_Random()) << 11);
 	mo = P_SpawnMobj(x, y, z, rtype);
 	if (mo)
 	{
 		mo->target = actor;
-		mo->momx = (P_Random() - 128) << 10;
-		mo->momy = (P_Random() - 128) << 10;
+		mo->momx = (P_Random3()) << 10;
+		mo->momy = (P_Random3()) << 10;
 		mo->momz = (P_Random() << 10);
 		mo->special1 = 2;	// Number bounces
 	}
@@ -3640,15 +3658,15 @@
 	mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FIREDEMON_SPLOTCH1);
 	if (mo)
 	{
-		mo->momx = (P_Random() - 128) << 11;
-		mo->momy = (P_Random() - 128) << 11;
+		mo->momx = (P_Random3()) << 11;
+		mo->momy = (P_Random3()) << 11;
 		mo->momz = FRACUNIT*3 + (P_Random() << 10);
 	}
 	mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FIREDEMON_SPLOTCH2);
 	if (mo)
 	{
-		mo->momx = (P_Random() - 128) << 11;
-		mo->momy = (P_Random() - 128) << 11;
+		mo->momx = (P_Random3()) << 11;
+		mo->momy = (P_Random3()) << 11;
 		mo->momz = FRACUNIT*3 + (P_Random() << 10);
 	}
 }
@@ -3668,7 +3686,7 @@
 	A_Look(actor);
 	if (P_Random() < 64)
 	{
-		dist = ((P_Random() - 128) * actor->radius) >> 7;
+		dist = ((P_Random3()) * actor->radius) >> 7;
 		an = (actor->angle + ANG90) >> ANGLETOFINESHIFT;
 
 		P_SpawnMobj(actor->x + FixedMul(dist, finecosine[an]),
@@ -3693,7 +3711,7 @@
 	A_Chase(actor);
 	if (P_Random() < 128)
 	{
-		dist = ((P_Random() - 128) * actor->radius) >> 7;
+		dist = ((P_Random3()) * actor->radius) >> 7;
 		an = (actor->angle + ANG90) >> ANGLETOFINESHIFT;
 
 		mo = P_SpawnMobj(actor->x + FixedMul(dist, finecosine[an]),
@@ -4710,6 +4728,8 @@
 	int i;
 	mobj_t *mo;
 
+	int a, b, c;
+
 	if (actor->momx || actor->momy || actor->momz)
 	{
 		actor->tics = 105;
@@ -4719,29 +4739,35 @@
 
 	for (i = 12 + (P_Random() & 15); i >= 0; i--)
 	{
-		mo = P_SpawnMobj(actor->x + (((P_Random() - 128) * actor->radius) >> 7),
-				 actor->y + (((P_Random() - 128) * actor->radius) >> 7),
-				 actor->z + (P_Random() * actor->height / 255), MT_ICECHUNK);
+		c = (P_Random() * actor->height / 255);
+		b = (((P_Random3()) * actor->radius) >> 7);
+		a = (((P_Random3()) * actor->radius) >> 7);
+		mo = P_SpawnMobj(actor->x + a,
+				 actor->y + b,
+				 actor->z + c, MT_ICECHUNK);
 		P_SetMobjState(mo, mo->info->spawnstate + (P_Random() % 3));
 		if (mo)
 		{
 			mo->momz = FixedDiv(mo->z - actor->z, actor->height)<<2;
-			mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7);
-			mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7);
+			mo->momx = (P_Random2()) << (FRACBITS - 7);
+			mo->momy = (P_Random2()) << (FRACBITS - 7);
 			A_IceSetTics(mo);	// set a random tic wait
 		}
 	}
 	for (i = 12 + (P_Random() & 15); i >= 0; i--)
 	{
-		mo = P_SpawnMobj(actor->x + (((P_Random() - 128) * actor->radius) >> 7),
-				 actor->y + (((P_Random() - 128) * actor->radius) >> 7),
-				 actor->z + (P_Random() * actor->height / 255), MT_ICECHUNK);
+		c = (P_Random() * actor->height / 255);
+		b = (((P_Random3()) * actor->radius) >> 7);
+		a = (((P_Random3()) * actor->radius) >> 7);
+		mo = P_SpawnMobj(actor->x + a,
+				 actor->y + b,
+				 actor->z + c, MT_ICECHUNK);
 		P_SetMobjState(mo, mo->info->spawnstate + (P_Random() % 3));
 		if (mo)
 		{
 			mo->momz = FixedDiv(mo->z - actor->z, actor->height)<<2;
-			mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7);
-			mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7);
+			mo->momx = (P_Random2()) << (FRACBITS - 7);
+			mo->momy = (P_Random2()) << (FRACBITS - 7);
 			A_IceSetTics(mo);	// set a random tic wait
 		}
 	}
@@ -4750,8 +4776,8 @@
 		mo = P_SpawnMobj(actor->x, actor->y, actor->z + VIEWHEIGHT, MT_ICECHUNK);
 		P_SetMobjState(mo, S_ICECHUNK_HEAD);
 		mo->momz = FixedDiv(mo->z - actor->z, actor->height)<<2;
-		mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7);
-		mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7);
+		mo->momx = (P_Random2()) << (FRACBITS - 7);
+		mo->momy = (P_Random2()) << (FRACBITS - 7);
 		mo->flags2 |= MF2_ICEDAMAGE; // used to force blue palette
 		mo->flags2 &= ~MF2_FLOORCLIP;
 		mo->player = actor->player;
--- a/p_mobj.c
+++ b/p_mobj.c
@@ -1180,6 +1180,10 @@
 	mobjinfo_t *info;
 	fixed_t space;
 
+	//fprint(2, "%d %d %d\n", x, y, z);
+	//if(x == -22118400 && y == 15941632 && z == -4145152)
+	//	abort();
+
 	mobj = (mobj_t *) Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL);
 	memset(mobj, 0, sizeof(*mobj));
 	info = &mobjinfo[type];
@@ -1760,7 +1764,7 @@
 {
 	mobj_t *puff;
 
-	z += ((P_Random() - P_Random()) << 10);
+	z += ((P_Random2()) << 10);
 	puff = P_SpawnMobj(x, y, z, PuffType);
 	if (linetarget && puff->info->seesound)
 	{ // Hit thing sound
@@ -1797,7 +1801,7 @@
 {
 	mobj_t	*th;
 
-	z += ((P_Random() - P_Random()) << 10);
+	z += ((P_Random2()) << 10);
 	th = P_SpawnMobj (x, y, z, MT_BLOOD);
 	th->momz = FRACUNIT*2;
 	th->tics -= P_Random() & 3;
@@ -1821,8 +1825,8 @@
 
 	mo = P_SpawnMobj(x, y, z, MT_BLOODSPLATTER);
 	mo->target = originator;
-	mo->momx = (P_Random() - P_Random()) << 10;
-	mo->momy = (P_Random() - P_Random()) << 10;
+	mo->momx = (P_Random2()) << 10;
+	mo->momy = (P_Random2()) << 10;
 	mo->momz = 3*FRACUNIT;
 }
 
@@ -1835,9 +1839,12 @@
 void P_BloodSplatter2(fixed_t x, fixed_t y, fixed_t z, mobj_t *originator)
 {
 	mobj_t *mo;
+	int a, b;
 
-	mo = P_SpawnMobj(x + ((P_Random() - 128) <<11),
-			 y + ((P_Random() - 128) <<11),
+	b = ((P_Random3()) <<11);
+	a = ((P_Random3()) <<11);
+	mo = P_SpawnMobj(x + a,
+			 y + b,
 			 z, MT_AXEBLOOD);
 	mo->target = originator;
 }
@@ -1853,9 +1860,9 @@
 	mobj_t *th;
 	fixed_t x, y, z;
 
-	x = mo->x + ((P_Random() - P_Random()) <<12);
-	y = mo->y + ((P_Random() - P_Random()) <<12);
-	z = mo->z + ((P_Random() - P_Random()) <<12);
+	x = mo->x + ((P_Random2()) <<12);
+	y = mo->y + ((P_Random2()) <<12);
+	z = mo->z + ((P_Random2()) <<12);
 	th = P_SpawnMobj(x, y, z, MT_BLOOD);
 //	th->flags |= MF_NOGRAVITY;
 	th->momx = mo->momx>>1;
@@ -1942,8 +1949,8 @@
 		{
 			mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SPLASH);
 			mo->target = thing;
-			mo->momx = (P_Random() - P_Random()) <<8;
-			mo->momy = (P_Random() - P_Random()) <<8;
+			mo->momx = (P_Random2()) <<8;
+			mo->momy = (P_Random2()) <<8;
 			mo->momz = 2*FRACUNIT + (P_Random() <<8);
 			mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SPLASHBASE);
 			if (thing->player)
@@ -1985,8 +1992,8 @@
 		{
 			mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SLUDGECHUNK);
 			mo->target = thing;
-			mo->momx = (P_Random() - P_Random()) <<8;
-			mo->momy = (P_Random() - P_Random()) <<8;
+			mo->momx = (P_Random2()) <<8;
+			mo->momy = (P_Random2()) <<8;
 			mo->momz = FRACUNIT + (P_Random() <<8);
 			mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SLUDGESPLASH);
 			if (thing->player)
@@ -2098,7 +2105,7 @@
 	an = R_PointToAngle2(source->x, source->y, dest->x, dest->y);
 	if (dest->flags & MF_SHADOW)
 	{ // Invisible target
-		an += (P_Random() - P_Random()) <<21;
+		an += (P_Random2()) <<21;
 	}
 	th->angle = an;
 	an >>= ANGLETOFINESHIFT;
@@ -2140,7 +2147,7 @@
 	an = R_PointToAngle2(source->x, source->y, dest->x, dest->y);
 	if (dest->flags & MF_SHADOW)
 	{ // Invisible target
-		an += (P_Random() - P_Random()) <<21;
+		an += (P_Random2()) <<21;
 	}
 	th->angle = an;
 	an >>= ANGLETOFINESHIFT;
@@ -2474,7 +2481,7 @@
 	an = R_PointToAngle2(x, y, dest->x, dest->y);
 	if (dest->flags & MF_SHADOW)
 	{ // Invisible target
-		an += (P_Random() - P_Random()) <<21;
+		an += (P_Random2()) <<21;
 	}
 	th->angle = an;
 	an >>= ANGLETOFINESHIFT;
--- a/p_pspr.c
+++ b/p_pspr.c
@@ -898,12 +898,16 @@
 void A_FSwordFlames(mobj_t *actor)
 {
 	int i;
+	int a, b, c;
 
 	for (i = 1 + (P_Random() & 3); i; i--)
 	{
-		P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
-			    actor->y + ((P_Random() - 128) << 12),
-			    actor->z + ((P_Random() - 128) << 11),
+		c = ((P_Random3()) << 11);	
+		b = ((P_Random3()) << 12);
+		a = ((P_Random3()) << 12);
+		P_SpawnMobj(actor->x + a,
+			    actor->y + b,
+			    actor->z + c,
 			    MT_FSWORD_FLAME);
 	}
 }
@@ -1016,6 +1020,7 @@
 {
 	mobj_t *mo;
 	fixed_t deltaZ;
+	int a, b;
 
 	A_LightningClip(actor);
 
@@ -1033,8 +1038,10 @@
 	{
 		deltaZ = -10*FRACUNIT;
 	}
-	mo = P_SpawnMobj(actor->x + ((P_Random() - 128) * actor->radius/256),
-			 actor->y + ((P_Random() - 128) * actor->radius/256),
+	b = ((P_Random3()) * actor->radius/256);
+	a = ((P_Random3()) * actor->radius/256);
+	mo = P_SpawnMobj(actor->x + a,
+			 actor->y + b,
 			 actor->z + deltaZ, MT_LIGHTNING_ZAP);
 	if (mo)
 	{
@@ -1051,26 +1058,6 @@
 			mo->momz = -20*FRACUNIT;
 		}
 	}
-	/*
-	mo = P_SpawnMobj(actor->x + ((P_Random() - 128) * actor->radius/256),
-			 actor->y + ((P_Random() - 128) * actor->radius/256),
-			 actor->z+deltaZ, MT_LIGHTNING_ZAP);
-	if (mo)
-	{
-		mo->special2 = (intptr_t)actor;
-		mo->momx = actor->momx;
-		mo->momy = actor->momy;
-		mo->target = actor->target;
-		if (actor->type == MT_LIGHTNING_FLOOR)
-		{
-			mo->momz = 16*FRACUNIT;
-		}
-		else
-		{
-			mo->momz = -16*FRACUNIT;
-		}
-	}
-	*/
 	if (actor->type == MT_LIGHTNING_FLOOR && P_Random() < 160)
 	{
 		S_StartSound(actor, SFX_MAGE_LIGHTNING_CONTINUOUS);
@@ -1420,7 +1407,8 @@
 	int i;
 	int useMana;
 
-	damage = 40 + (P_Random() & 15) + (P_Random() & 7);
+	damage = 40 + (P_Random() & 15);
+	damage += (P_Random() & 7);
 	power = 0;
 	if (player->mana[MANA_1] > 0)
 	{
@@ -1885,6 +1873,7 @@
 	int i;
 	mobj_t *mo;
 	mobj_t *tail, *next;
+	int a, b;
 
 	for (j = 0; j < 4; j++)
 	{
@@ -1905,7 +1894,9 @@
 			mo->special2 = (32 + (P_Random() & 7)) << 16;	// lower-left
 			break;
 		case 3:
-			mo->special2 = ((32 + (P_Random() & 7)) << 16) + 32 + (P_Random() & 7);
+			a = ((32 + (P_Random() & 7)) << 16);
+			b = 32 + (P_Random() & 7);
+			mo->special2 = a + b;
 			break;
 		}
 		mo->z = actor->z;