From ef6430c23eaadca8a78285d82fa7a53b0e2495a1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 15 Feb 2016 20:34:53 +0000 Subject: [PATCH 01/51] Fix respawning rings on slopes --- src/p_mobj.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 25ae8815a..f240c40f2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8171,7 +8171,11 @@ void P_RespawnSpecials(void) if (mthing->options & MTF_OBJECTFLIP) { - z = ss->sector->ceilingheight - (mthing->options >> ZSHIFT) * FRACUNIT; + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT; if (mthing->options & MTF_AMBUSH && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) z -= 24*FRACUNIT; @@ -8179,7 +8183,11 @@ void P_RespawnSpecials(void) } else { - z = ss->sector->floorheight + (mthing->options >> ZSHIFT) * FRACUNIT; + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT; if (mthing->options & MTF_AMBUSH && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) z += 24*FRACUNIT; From b5673ed101741b44562e4466f1369558c16b5d54 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 15 Feb 2016 20:46:56 +0000 Subject: [PATCH 02/51] Fix player spawning on slopes --- src/p_mobj.c | 60 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f240c40f2..30c061d1e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8357,7 +8357,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) fixed_t z; sector_t *sector; - + fixed_t floor, ceiling; player_t *p = &players[playernum]; mobj_t *mobj = p->mo; @@ -8373,19 +8373,31 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) // set Z height sector = R_PointInSubsector(x, y)->sector; + + floor = +#ifdef ESLOPE + sector->f_slope ? P_GetZAt(sector->f_slope, x, y) : +#endif + sector->floorheight; + ceiling = +#ifdef ESLOPE + sector->c_slope ? P_GetZAt(sector->c_slope, x, y) : +#endif + sector->ceilingheight; + if (mthing) { // Flagging a player's ambush will make them start on the ceiling // Objectflip inverts if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) { - z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; + z = ceiling - mobjinfo[MT_PLAYER].height; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sector->floorheight; + z = floor; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -8397,15 +8409,15 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) } } else - z = sector->floorheight; + z = floor; - if (z < sector->floorheight) - z = sector->floorheight; - else if (z > sector->ceilingheight - mobjinfo[MT_PLAYER].height) - z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; + if (z < floor) + z = floor; + else if (z > ceiling - mobjinfo[MT_PLAYER].height) + z = ceiling - mobjinfo[MT_PLAYER].height; - mobj->floorz = sector->floorheight; - mobj->ceilingz = sector->ceilingheight; + mobj->floorz = floor; + mobj->ceilingz = ceiling; P_UnsetThingPosition(mobj); mobj->x = x; @@ -8413,7 +8425,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) P_SetThingPosition(mobj); mobj->z = z; - if (mobj->z == sector->floorheight) + if (mobj->z == mobj->floorz) mobj->eflags |= MFE_ONGROUND; mobj->angle = angle; @@ -8425,6 +8437,7 @@ void P_MovePlayerToStarpost(INT32 playernum) { fixed_t z; sector_t *sector; + fixed_t floor, ceiling; player_t *p = &players[playernum]; mobj_t *mobj = p->mo; @@ -8436,14 +8449,25 @@ void P_MovePlayerToStarpost(INT32 playernum) P_SetThingPosition(mobj); sector = R_PointInSubsector(mobj->x, mobj->y)->sector; - z = p->starpostz << FRACBITS; - if (z < sector->floorheight) - z = sector->floorheight; - else if (z > sector->ceilingheight - mobjinfo[MT_PLAYER].height) - z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; + floor = +#ifdef ESLOPE + sector->f_slope ? P_GetZAt(sector->f_slope, x, y) : +#endif + sector->floorheight; + ceiling = +#ifdef ESLOPE + sector->c_slope ? P_GetZAt(sector->c_slope, x, y) : +#endif + sector->ceilingheight; - mobj->floorz = sector->floorheight; - mobj->ceilingz = sector->ceilingheight; + z = p->starpostz << FRACBITS; + if (z < floor) + z = floor; + else if (z > ceiling - mobjinfo[MT_PLAYER].height) + z = ceiling - mobjinfo[MT_PLAYER].height; + + mobj->floorz = floor; + mobj->ceilingz = ceiling; mobj->z = z; if (mobj->z == mobj->floorz) From fa1bc5a09bb4ea7e69fc602d56b91d2ae685a651 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 15 Feb 2016 20:55:57 +0000 Subject: [PATCH 03/51] Whoops forgot this for last commit --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 30c061d1e..65b5f9a09 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8451,12 +8451,12 @@ void P_MovePlayerToStarpost(INT32 playernum) floor = #ifdef ESLOPE - sector->f_slope ? P_GetZAt(sector->f_slope, x, y) : + sector->f_slope ? P_GetZAt(sector->f_slope, mobj->x, mobj->y) : #endif sector->floorheight; ceiling = #ifdef ESLOPE - sector->c_slope ? P_GetZAt(sector->c_slope, x, y) : + sector->c_slope ? P_GetZAt(sector->c_slope, mobj->x, mobj->y) : #endif sector->ceilingheight; From 03470118cd8214d75f220e009b14375051a7e4ea Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 15 Feb 2016 20:57:35 +0000 Subject: [PATCH 04/51] Added missing ESLOPE ifdef from when I first did these fixes for slope compiling --- src/r_segs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/r_segs.c b/src/r_segs.c index 04873b29c..591242693 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1479,9 +1479,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) maskedtextureheight = NULL; +#ifdef ESLOPE //initialize segleft and segright memset(&segleft, 0x00, sizeof(segleft)); memset(&segright, 0x00, sizeof(segright)); +#endif if (ds_p == drawsegs+maxdrawsegs) { From 3058648fdc1f0ec8723a0e2a273d66b067c575f2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 16 Feb 2016 17:58:08 +0000 Subject: [PATCH 05/51] Fix elemental flame trails not spawning when going up slopes --- src/p_user.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 96841d7e0..d5ff80f6e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6193,6 +6193,14 @@ void P_ElementalFireTrail(player_t *player) { newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); +#ifdef ESLOPE + if (player->mo->standingslope) + { + ground = P_GetZAt(player->mo->standingslope, newx, newy); + if (player->mo->eflags & MFE_VERTICALFLIP) + ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); + } +#endif flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); P_SetTarget(&flame->target, player->mo); flame->angle = travelangle; From 3802ec33de3738426a48f751205240314de36a51 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 23 Feb 2016 22:53:24 +0000 Subject: [PATCH 06/51] Fixed how dying players who were standing on slopes just jump off to the side --- src/p_map.c | 29 +++++++++++++++++------------ src/p_mobj.c | 14 ++++++++++++-- src/p_slopes.c | 3 +++ 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 7ff913a86..dff5c5bef 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2051,21 +2051,26 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->ceilingz = tmceilingz; #ifdef ESLOPE - // Assign thing's standingslope if needed - if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { - if (!startingonground && tmfloorslope) - P_HandleSlopeLanding(thing, tmfloorslope); + if (!(thing->flags & MF_NOCLIPHEIGHT)) + { + // Assign thing's standingslope if needed + if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmfloorslope) + P_HandleSlopeLanding(thing, tmfloorslope); - if (thing->momz <= 0) - thing->standingslope = tmfloorslope; - } - else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { - if (!startingonground && tmceilingslope) - P_HandleSlopeLanding(thing, tmceilingslope); + if (thing->momz <= 0) + thing->standingslope = tmfloorslope; + } + else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmceilingslope) + P_HandleSlopeLanding(thing, tmceilingslope); - if (thing->momz >= 0) - thing->standingslope = tmceilingslope; + if (thing->momz >= 0) + thing->standingslope = tmceilingslope; + } } + else // don't set standingslope if you're not going to clip against it + thing->standingslope = NULL; #endif thing->x = x; diff --git a/src/p_mobj.c b/src/p_mobj.c index 65b5f9a09..155d985e9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2077,8 +2077,13 @@ static boolean P_ZMovement(mobj_t *mo) I_Assert(!P_MobjWasRemoved(mo)); #ifdef ESLOPE - if (mo->standingslope && !P_IsObjectOnGround(mo)) + if (mo->standingslope) + { + if (mo->flags & MF_NOCLIPHEIGHT) + mo->standingslope = NULL; + else if (!P_IsObjectOnGround(mo)) P_SlopeLaunch(mo); + } #endif // Intercept the stupid 'fall through 3dfloors' bug @@ -2561,8 +2566,13 @@ static void P_PlayerZMovement(mobj_t *mo) return; #ifdef ESLOPE - if (mo->standingslope && !P_IsObjectOnGround(mo)) + if (mo->standingslope) + { + if (mo->flags & MF_NOCLIPHEIGHT) + mo->standingslope = NULL; + else if (!P_IsObjectOnGround(mo)) P_SlopeLaunch(mo); + } #endif // clip movement diff --git a/src/p_slopes.c b/src/p_slopes.c index 2d55cf194..797fe46b4 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -1099,6 +1099,9 @@ void P_ButteredSlope(mobj_t *mo) if (!mo->standingslope) return; + if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY)) + return; // don't slide down slopes if you can't touch them or you're not affected by gravity + if (mo->player) { if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING)) return; // Don't slide on non-steep slopes unless spinning From 98fd5ca63b32f9060bdb3e117edc6297c544aea0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 1 Mar 2016 19:55:13 +0000 Subject: [PATCH 07/51] Made some FOF-related seg code account for slopes, as requested by some TODOs The funny thing is you really can't see ANY change here unless you have a sloped FOF intersecting a sector floor/ceiling (and a second FOF on the other side), which has other problems anyway lol --- src/r_segs.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 591242693..ccf70338e 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2121,8 +2121,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (r2 = frontsector->ffloors; r2; r2 = r2->next) { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) continue; if (r2->norender == leveltime) @@ -2154,9 +2153,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) } else low2 = lowslope2 = *r2->bottomheight; + if ((high2 < lowcut && highslope2 < lowcutslope) || (low2 > highcut && lowslope2 > highcutslope)) + continue; if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) continue; #else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; #endif @@ -2201,8 +2204,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (r2 = backsector->ffloors; r2; r2 = r2->next) { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) continue; if (r2->norender == leveltime) @@ -2234,9 +2236,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) } else low2 = lowslope2 = *r2->bottomheight; + if ((high2 < lowcut && highslope2 < lowcutslope) || (low2 > highcut && lowslope2 > highcutslope)) + continue; if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) continue; #else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; #endif From 099e25824fcb3cbda74256e0d16e0255475b0176 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 5 Mar 2016 16:29:25 +0000 Subject: [PATCH 08/51] First person view now should correctly take the skybox centerpoint's angle into account --- src/r_main.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index a4e72cba9..b1a2036cc 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -972,14 +972,42 @@ void R_SkyboxFrame(player_t *player) { if (skyboxmo[1]) { + fixed_t x = 0, y = 0; if (mh->skybox_scalex > 0) - viewx += (player->mo->x - skyboxmo[1]->x) / mh->skybox_scalex; + x = (player->mo->x - skyboxmo[1]->x) / mh->skybox_scalex; else if (mh->skybox_scalex < 0) - viewx += (player->mo->x - skyboxmo[1]->x) * -mh->skybox_scalex; + x = (player->mo->x - skyboxmo[1]->x) * -mh->skybox_scalex; if (mh->skybox_scaley > 0) - viewy += (player->mo->y - skyboxmo[1]->y) / mh->skybox_scaley; + y = (player->mo->y - skyboxmo[1]->y) / mh->skybox_scaley; else if (mh->skybox_scaley < 0) - viewy += (player->mo->y - skyboxmo[1]->y) * -mh->skybox_scaley; + y = (player->mo->y - skyboxmo[1]->y) * -mh->skybox_scaley; + + if (viewmobj->angle == 0) + { + viewx += x; + viewy += y; + } + else if (viewmobj->angle == ANGLE_90) + { + viewx -= y; + viewy += x; + } + else if (viewmobj->angle == ANGLE_180) + { + viewx -= x; + viewy -= y; + } + else if (viewmobj->angle == ANGLE_270) + { + viewx += y; + viewy -= x; + } + else + { + angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT; + viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); + viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); + } } if (mh->skybox_scalez > 0) viewz += player->viewz / mh->skybox_scalez; From 2f539a4df98b43c318a7382e8664dc88e1751c9a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 7 Mar 2016 20:42:25 +0000 Subject: [PATCH 09/51] R_RenderThickSideRange now checks for slopes in the front sector's lightlist This appears to fix a few holes that have been known to appear with FOF slopes sometimes, dunno how they actually came about exactly but this apparently sorts them out --- src/r_segs.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/r_segs.c b/src/r_segs.c index ccf70338e..8222a7268 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -673,7 +673,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t offsetvalue = 0; lightlist_t *light; r_lightlist_t *rlight; +#ifndef ESLOPE fixed_t lheight; +#endif line_t *newline = NULL; #ifdef ESLOPE // Render FOF sides kinda like normal sides, with the frac and step and everything @@ -751,9 +753,49 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) for (i = p = 0; i < dc_numlights; i++) { +#ifdef ESLOPE + fixed_t leftheight, rightheight; + fixed_t pfloorleft, pfloorright; +#endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); + rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); + } else + leftheight = rightheight = light->height; + if (*pfloor->b_slope) { + pfloorleft = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y); + pfloorright = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y); + } else + pfloorleft = pfloorright = *pfloor->bottomheight; + + if (leftheight < pfloorleft && rightheight < pfloorright) + continue; + + if (*pfloor->t_slope) { + pfloorleft = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y); + pfloorright = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y); + } else + pfloorleft = pfloorright = *pfloor->topheight; + + if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) + { + lightlist_t *nextlight = &frontsector->lightlist[i+1]; + if (nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height > pfloorleft + && nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height > pfloorright) + continue; + } + + leftheight -= viewz; + rightheight -= viewz; + rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(ds->x2-ds->x1+1); + rlight->height -= rlight->heightstep; +#else if (light->height < *pfloor->bottomheight) continue; @@ -763,13 +805,29 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->heightstep; +#endif rlight->flags = light->flags; - if (light->flags & FF_CUTLEVEL) { +#ifdef ESLOPE + if (*light->caster->b_slope) { + leftheight = P_GetZAt(*light->caster->b_slope, ds->leftpos.x, ds->leftpos.y); + rightheight = P_GetZAt(*light->caster->b_slope, ds->rightpos.x, ds->rightpos.y); + } else + leftheight = rightheight = light->caster->bottomheight; + + leftheight -= viewz; + rightheight -= viewz; + + rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(ds->x2-ds->x1+1); + rlight->botheight -= rlight->botheightstep; +#else lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->botheightstep; +#endif } rlight->lightlevel = *light->lightlevel; From 60ea2ecb77b4bb0926169d7bf879b2dfbf387a50 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 7 Mar 2016 21:02:35 +0000 Subject: [PATCH 10/51] Whoops, forgot these --- src/r_segs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_segs.c b/src/r_segs.c index 8222a7268..e31d570b6 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -814,7 +814,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) leftheight = P_GetZAt(*light->caster->b_slope, ds->leftpos.x, ds->leftpos.y); rightheight = P_GetZAt(*light->caster->b_slope, ds->rightpos.x, ds->rightpos.y); } else - leftheight = rightheight = light->caster->bottomheight; + leftheight = rightheight = *light->caster->bottomheight; leftheight -= viewz; rightheight -= viewz; From 436bcdf19aa9da266e421326e7129a848dd036a6 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Tue, 8 Mar 2016 23:43:43 -0800 Subject: [PATCH 11/51] Objectplace handles slopes. Sorry MI, I'm hijacking your branch for a bit. --- src/m_cheat.c | 85 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 473fbbf75..51b414df3 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -31,6 +31,7 @@ #include "v_video.h" #include "z_zone.h" +#include "p_slopes.h" #include "lua_script.h" #include "lua_hook.h" @@ -857,9 +858,19 @@ static void OP_CycleThings(INT32 amt) static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) { + sector_t *sec = player->mo->subsector->sector; + if (ceiling) { - if (((player->mo->subsector->sector->ceilingheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) +#ifdef ESLOPE + // Truncate position to match where mapthing would be when spawned + // (this applies to every further P_GetZAt call as well) + fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; +#else + fixed_t cheight = sec->ceilingheight; +#endif + + if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) { CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("low"), (1 << (16-ZSHIFT)), M_GetText("below top ceiling")); @@ -868,7 +879,12 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) } else { - if (((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) +#ifdef ESLOPE + fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; +#else + fixed_t fheight = sec->floorheight; +#endif + if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) { CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"), (1 << (16-ZSHIFT)), M_GetText("above bottom floor")); @@ -881,6 +897,7 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling) { mapthing_t *mt = mapthings; + sector_t *sec = player->mo->subsector->sector; #ifdef HAVE_BLUA LUA_InvalidateMapthings(); @@ -913,9 +930,23 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c mt->x = (INT16)(player->mo->x>>FRACBITS); mt->y = (INT16)(player->mo->y>>FRACBITS); if (ceiling) - mt->options = (UINT16)((player->mo->subsector->sector->ceilingheight - player->mo->z - player->mo->height)>>FRACBITS); + { +#ifdef ESLOPE + fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->ceilingheight; +#else + fixed_t cheight = sec->ceilingheight; +#endif + mt->options = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); + } else - mt->options = (UINT16)((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS); + { +#ifdef ESLOPE + fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->floorheight; +#else + fixed_t fheight = sec->floorheight; +#endif + mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS); + } mt->options <<= ZSHIFT; mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle))); @@ -969,6 +1000,13 @@ void OP_NightsObjectplace(player_t *player) { UINT16 angle = (UINT16)(player->anotherflyangle % 360); INT16 temp = (INT16)FixedInt(AngleFixed(player->mo->angle)); // Traditional 2D Angle + sector_t *sec = player->mo->subsector->sector; +#ifdef ESLOPE + fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; +#else + fixed_t fheight = sec->floorheight; +#endif + player->pflags |= PF_ATTACKDOWN; @@ -983,7 +1021,7 @@ void OP_NightsObjectplace(player_t *player) temp += 90; temp %= 360; - mt->options = (UINT16)((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS); + mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS); mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8)); P_SpawnHoopsAndRings(mt); @@ -1117,6 +1155,33 @@ void OP_ObjectplaceMovement(player_t *player) else player->viewz = player->mo->z + player->viewheight; + // Display flag information + // Moved up so it always updates. + { + sector_t *sec = player->mo->subsector->sector; + + if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP)) + { +#ifdef ESLOPE + fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; +#else + fixed_t cheight = sec->ceilingheight; +#endif + op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS); + } + else + { +#ifdef ESLOPE + fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; +#else + fixed_t fheight = sec->floorheight; +#endif + op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS); + } + op_displayflags <<= ZSHIFT; + op_displayflags |= (UINT16)cv_opflags.value; + } + if (player->pflags & PF_ATTACKDOWN) { // Are ANY objectplace buttons pressed? If no, remove flag. @@ -1182,16 +1247,6 @@ void OP_ObjectplaceMovement(player_t *player) CONS_Printf(M_GetText("Placed object type %d at %d, %d, %d, %d\n"), mt->type, mt->x, mt->y, mt->options>>ZSHIFT, mt->angle); } - - // Display flag information - { - if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP)) - op_displayflags = (UINT16)((player->mo->subsector->sector->ceilingheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS); - else - op_displayflags = (UINT16)((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS); - op_displayflags <<= ZSHIFT; - op_displayflags |= (UINT16)cv_opflags.value; - } } // From c67683eb0af0351396a93120b3f14199964ac983 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 12 Mar 2016 19:59:32 +0000 Subject: [PATCH 12/51] Fixed slope walls displaying sprites through them if they weren't completely above you Sadly this does not fix ALL sprite issues, but just some of them at the least --- src/r_segs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index e31d570b6..fdae62d50 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1859,7 +1859,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) { ds_p->silhouette = SIL_BOTTOM; #ifdef ESLOPE - ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); + if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + ds_p->bsilheight = INT32_MAX; + else + ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); #else ds_p->bsilheight = frontsector->floorheight; #endif @@ -1883,7 +1886,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) { ds_p->silhouette |= SIL_TOP; #ifdef ESLOPE - ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); + if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + ds_p->tsilheight = INT32_MIN; + else + ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); #else ds_p->tsilheight = frontsector->ceilingheight; #endif From accab7da6a05f79f5ea0e3d2db4a76ff4052f8da Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 12 Mar 2016 23:03:56 +0000 Subject: [PATCH 13/51] Fixed precipitation not checking for slopes --- src/p_mobj.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f074917bf..90a7daa9b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3710,10 +3710,15 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) mobjsecsubsec = mobj->subsector->sector; else return; - mobj->floorz = mobjsecsubsec->floorheight; + mobj->floorz = +#ifdef ESLOPE + mobjsecsubsec->f_slope ? P_GetZAt(mobjsecsubsec->f_slope, mobj->x, mobj->y) : +#endif + mobjsecsubsec->floorheight; if (mobjsecsubsec->ffloors) { ffloor_t *rover; + fixed_t topheight; for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next) { @@ -3724,8 +3729,15 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE)) continue; - if (*rover->topheight > mobj->floorz) - mobj->floorz = *rover->topheight; +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + else +#endif + topheight = *rover->topheight; + + if (topheight > mobj->floorz) + mobj->floorz = topheight; } } } @@ -7768,6 +7780,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype { state_t *st; precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); + fixed_t starting_floorz; mobj->x = x; mobj->y = y; @@ -7786,8 +7799,16 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype // set subsector and/or block links P_SetPrecipitationThingPosition(mobj); - mobj->floorz = mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->ceilingheight; + mobj->floorz = starting_floorz = +#ifdef ESLOPE + mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) : +#endif + mobj->subsector->sector->floorheight; + mobj->ceilingz = +#ifdef ESLOPE + mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) : +#endif + mobj->subsector->sector->ceilingheight; mobj->z = z; mobj->momz = mobjinfo[type].speed; @@ -7797,7 +7818,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype CalculatePrecipFloor(mobj); - if (mobj->floorz != mobj->subsector->sector->floorheight) + if (mobj->floorz != starting_floorz) mobj->precipflags |= PCF_FOF; else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7 || GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6 From e941687d4c0ebe229415da976c9a830ef0413f70 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 18 Mar 2016 20:33:16 +0000 Subject: [PATCH 14/51] R_RenderMaskedSegRange now checks for slopes in the sector lightlist in other words, midtexture rendering should now correctly account for slopes from FOFs that could affect lighting/colormap --- src/r_segs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/r_segs.c b/src/r_segs.c index fdae62d50..72315982d 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -360,10 +360,30 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) for (i = 0; i < dc_numlights; i++) { +#ifdef ESLOPE + fixed_t leftheight, rightheight; +#endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[i]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); + rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); + } else + leftheight = rightheight = light->height; + + leftheight -= viewz; + rightheight -= viewz; + + rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(ds->x2-ds->x1+1); + //if (x1 > ds->x1) + //rlight->height -= (x1 - ds->x1)*rlight->heightstep; +#else rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); +#endif rlight->lightlevel = *light->lightlevel; rlight->extra_colormap = light->extra_colormap; rlight->flags = light->flags; From 6623a9148e98ecdbeb6d0abff2ea80b728dd8f07 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 18 Mar 2016 23:58:58 +0000 Subject: [PATCH 15/51] Fix HOMs by actually bothering to check if either side of a seg has slopes for height-checking code --- src/r_bsp.c | 72 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index c87d8baa7..cd32b7863 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -460,26 +460,64 @@ static void R_AddLine(seg_t *line) // Closed door. #ifdef ESLOPE - // Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than - // random renderer stopping around slopes... - if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) -#endif - if (backsector->ceilingheight <= frontsector->floorheight - || backsector->floorheight >= frontsector->ceilingheight) + if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope) { - goto clipsolid; + fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends + fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \ + end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight) + SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight) + SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight) + SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) +#undef SLOPEPARAMS + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) + { + goto clipsolid; + } + + // Check for automap fix. Store in doorclosed for r_segs.c + doorclosed = (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture) + && (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)); + + if (doorclosed) + goto clipsolid; + + // Window. + if (backc1 != frontc1 || backc2 != frontc2 + || backf1 != frontf1 || backf2 != frontf2) + { + goto clippass; + } } - - // Check for automap fix. Store in doorclosed for r_segs.c - doorclosed = R_DoorClosed(); - if (doorclosed) - goto clipsolid; - - // Window. - if (backsector->ceilingheight != frontsector->ceilingheight - || backsector->floorheight != frontsector->floorheight) + else +#endif { - goto clippass; + if (backsector->ceilingheight <= frontsector->floorheight + || backsector->floorheight >= frontsector->ceilingheight) + { + goto clipsolid; + } + + // Check for automap fix. Store in doorclosed for r_segs.c + doorclosed = R_DoorClosed(); + if (doorclosed) + goto clipsolid; + + // Window. + if (backsector->ceilingheight != frontsector->ceilingheight + || backsector->floorheight != frontsector->floorheight) + { + goto clippass; + } } // Reject empty lines used for triggers and special events. From a82c19adb1cb68e78f7eeb12e09e2c58d99f0cb1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 19 Mar 2016 16:19:58 +0000 Subject: [PATCH 16/51] Fix sprites displaying behind "closed doors" when slopes are present. For the record, thok barriers count as "closed doors" in SRB2 level contexts --- src/r_segs.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 72315982d..9ecb7708e 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1947,21 +1947,25 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->silhouette |= SIL_TOP; } -#ifdef ESLOPE - // This causes issues with slopes. - if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) -#endif //SoM: 3/25/2000: This code fixes an automap bug that didn't check // frontsector->ceiling and backsector->floor to see if a door was closed. // Without the following code, sprites get displayed behind closed doors. { +#ifdef ESLOPE + if (doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)) +#else if (doorclosed || backsector->ceilingheight <= frontsector->floorheight) +#endif { ds_p->sprbottomclip = negonearray; ds_p->bsilheight = INT32_MAX; ds_p->silhouette |= SIL_BOTTOM; } +#ifdef ESLOPE + if (doorclosed || (worldlow >= worldtop && worldlowslope >= worldtopslope)) +#else if (doorclosed || backsector->floorheight >= frontsector->ceilingheight) +#endif { // killough 1/17/98, 2/8/98 ds_p->sprtopclip = screenheightarray; ds_p->tsilheight = INT32_MIN; From 28631c30b70f89e337f8bd0a4ca9c0d5e3de59a7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 19 Mar 2016 22:25:49 +0000 Subject: [PATCH 17/51] Fix maskedtextureheight being set outside of ESLOPE code --- src/r_segs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 9ecb7708e..9689f43df 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1555,9 +1555,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif static size_t maxdrawsegs = 0; - maskedtextureheight = NULL; - #ifdef ESLOPE + maskedtextureheight = NULL; //initialize segleft and segright memset(&segleft, 0x00, sizeof(segleft)); memset(&segright, 0x00, sizeof(segright)); From ec5b272fa6ea8641b7d6d5d32c80f58cea74ea80 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 19 Mar 2016 23:19:05 +0000 Subject: [PATCH 18/51] Unless I'm mistaken, scalesteps/heightsteps should be divided by stop-start, not stop-start+1. Revert this commit if that was intentional. --- src/r_segs.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 9689f43df..02b243d4d 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -288,6 +288,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) line_t *ldef; sector_t *front, *back; INT32 times, repeats; + INT32 range; // Calculate light table. // Use different light tables @@ -334,6 +335,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) colfunc = fuzzcolfunc; } + range = max(ds->x2-ds->x1, 1); rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; @@ -377,7 +379,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); - rlight->heightstep = (rlight->heightstep-rlight->height)/(ds->x2-ds->x1+1); + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); //if (x1 > ds->x1) //rlight->height -= (x1 - ds->x1)*rlight->heightstep; #else @@ -693,6 +695,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t offsetvalue = 0; lightlist_t *light; r_lightlist_t *rlight; + INT32 range; #ifndef ESLOPE fixed_t lheight; #endif @@ -757,6 +760,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else if (pfloor->flags & FF_FOG) colfunc = R_DrawFogColumn_8; + range = max(ds->x2-ds->x1, 1); //SoM: Moved these up here so they are available for my lightlist calculations rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; @@ -813,7 +817,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rightheight -= viewz; rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); - rlight->heightstep = (rlight->heightstep-rlight->height)/(ds->x2-ds->x1+1); + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); rlight->height -= rlight->heightstep; #else if (light->height < *pfloor->bottomheight) @@ -841,7 +845,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1); rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); - rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(ds->x2-ds->x1+1); + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); rlight->botheight -= rlight->botheightstep; #else lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; @@ -951,8 +955,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) top_step = centeryfrac - FixedMul(right_top, ds->scale2); bottom_step = centeryfrac - FixedMul(right_bottom, ds->scale2); - top_step = (top_step-top_frac)/(ds->x2-ds->x1+1); - bottom_step = (bottom_step-bottom_frac)/(ds->x2-ds->x1+1); + top_step = (top_step-top_frac)/(range); + bottom_step = (bottom_step-bottom_frac)/(range); top_frac += top_step * (x1 - ds->x1); bottom_frac += bottom_step * (x1 - ds->x1); @@ -1549,6 +1553,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) INT32 i, p; lightlist_t *light; r_lightlist_t *rlight; + INT32 range; #ifdef ESLOPE vertex_t segleft, segright; fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; @@ -1633,7 +1638,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (stop > start) { ds_p->scale2 = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[stop]); - ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (stop-start); + range = stop-start; } else { @@ -1654,8 +1659,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #endif ds_p->scale2 = ds_p->scale1; + range = 1; } + ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range); + // calculate texture boundaries // and decide if floor / ceiling marks are needed #ifdef ESLOPE @@ -2531,11 +2539,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) #ifdef ESLOPE if (frontsector->c_slope) { fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); - topstep = (topfracend-topfrac)/(stop-start+1); + topstep = (topfracend-topfrac)/(range); } if (frontsector->f_slope) { fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); - bottomstep = (bottomfracend-bottomfrac)/(stop-start+1); + bottomstep = (bottomfracend-bottomfrac)/(range); } #endif @@ -2596,7 +2604,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) #ifdef ESLOPE rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); - rlight->heightstep = (rlight->heightstep-rlight->height)/(stop-start+1); + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); #else rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); @@ -2623,7 +2631,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); - rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(stop-start+1); + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); #else rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); @@ -2652,7 +2660,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) #ifdef ESLOPE ffloor[i].f_pos_slope >>= 4; ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); - ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(stop-start+1); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); #else ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); @@ -2681,7 +2689,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) #ifdef ESLOPE if (backsector->c_slope) { fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(stop-start+1); + pixhighstep = (topfracend-pixhigh)/(range); } #endif } @@ -2697,7 +2705,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) #ifdef ESLOPE if (backsector->f_slope) { fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(stop-start+1); + pixlowstep = (bottomfracend-pixlow)/(range); } #endif } @@ -2739,7 +2747,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; } @@ -2761,7 +2769,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; } #else @@ -2824,7 +2832,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; } @@ -2846,7 +2854,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; } #else From 6bda1a57a57f0367a97f13b21d38c4ddc37427a5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 29 Mar 2016 15:40:01 +0100 Subject: [PATCH 19/51] Fix FOF plane light underside checks --- src/r_bsp.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index cd32b7863..7f64e0cbd 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1002,7 +1002,7 @@ static void R_Subsector(size_t num) || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES)))) { light = R_GetPlaneLight(frontsector, planecenterz, - viewz < *rover->bottomheight); + viewz < heightcheck); ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, @@ -1020,12 +1020,7 @@ static void R_Subsector(size_t num) frontsector->hasslope = true; #endif - ffloor[numffloors].height = -#ifdef ESLOPE - *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : -#endif - *rover->bottomheight; - + ffloor[numffloors].height = heightcheck; ffloor[numffloors].ffloor = rover; numffloors++; } @@ -1050,7 +1045,7 @@ static void R_Subsector(size_t num) && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES)) || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES)))) { - light = R_GetPlaneLight(frontsector, planecenterz, viewz < *rover->topheight); + light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, @@ -1068,12 +1063,7 @@ static void R_Subsector(size_t num) frontsector->hasslope = true; #endif - ffloor[numffloors].height = -#ifdef ESLOPE - *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : -#endif - *rover->topheight; - + ffloor[numffloors].height = heightcheck; ffloor[numffloors].ffloor = rover; numffloors++; } From ef832dd8b815ec6a8753cf5515f3a72c9ba3a3ac Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 29 Mar 2016 18:59:56 +0100 Subject: [PATCH 20/51] Fixed how two adjacent FOFs can prevent each others' walls from displaying if they're at least partially covered Also some miscellaneous tweaks and changes to account for slopes properly --- src/r_segs.c | 58 ++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 02b243d4d..1f5477ecf 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2248,9 +2248,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) } else low2 = lowslope2 = *r2->bottomheight; - if ((high2 < lowcut && highslope2 < lowcutslope) || (low2 > highcut && lowslope2 > highcutslope)) + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) continue; - if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) continue; #else if (*r2->topheight < lowcut || *r2->bottomheight > highcut) @@ -2331,9 +2331,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) } else low2 = lowslope2 = *r2->bottomheight; - if ((high2 < lowcut && highslope2 < lowcutslope) || (low2 > highcut && lowslope2 > highcutslope)) + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) continue; - if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) continue; #else if (*r2->topheight < lowcut || *r2->bottomheight > highcut) @@ -2679,7 +2679,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldhigh < worldtop #ifdef ESLOPE - || worldhighslope <= worldtopslope + || worldhighslope < worldtopslope #endif ) { @@ -2696,7 +2696,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldlow > worldbottom #ifdef ESLOPE - || worldlowslope >= worldbottomslope + || worldlowslope > worldbottomslope #endif ) { @@ -2713,7 +2713,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { ffloor_t * rover; #ifdef ESLOPE - fixed_t rovertest; + fixed_t roverleft, roverright; fixed_t planevistest; #endif i = 0; @@ -2732,17 +2732,18 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) backsector->hasslope = true; - rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->bottomheight) - viewz; + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - if (rovertest>>4 <= worldhigh && - rovertest>>4 >= worldlow && + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) { //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); @@ -2754,17 +2755,18 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->topheight) - viewz; + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - if (rovertest>>4 <= worldhigh && - rovertest>>4 >= worldlow && + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) { //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); @@ -2817,17 +2819,18 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) frontsector->hasslope = true; - rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight) - viewz; + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - if (rovertest>>4 <= worldtop && - rovertest>>4 >= worldbottom && + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) { //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); @@ -2839,17 +2842,18 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight) - viewz; + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - if (rovertest>>4 <= worldtop && - rovertest>>4 >= worldbottom && + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) { //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); From ee00da6a74a62c74a56722b7b70fc50aa45c7f05 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 29 Mar 2016 22:32:09 +0100 Subject: [PATCH 21/51] Another thing that probably needed to check for slopes --- src/r_segs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/r_segs.c b/src/r_segs.c index 1f5477ecf..66413c588 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2032,8 +2032,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) markceiling = false; } +#ifdef ESLOPE + if ((worldhigh <= worldbottom && worldhighslope <= worldbottomslope) + || (worldlow >= worldtop && worldlowslope >= worldtopslope)) +#else if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) +#endif { // closed door markceiling = markfloor = true; From ce2c2de58a38c5a6f7270eabb80ae37c9084d590 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Sat, 26 Mar 2016 15:48:12 -0700 Subject: [PATCH 22/51] P_Random now using a variant of xorshift This actually passes most diehard tests, as opposed to the old RNG. It's also similarly fast. Internally the PRNG generates a fixed point number from [0,1) now, which makes P_RandomKey and P_RandomRange much easier to calculate. P_Random is just a simple shift, as well. Also, the lack of floating point math in P_RandomKey and P_RandomRange now is probably for the best. --- src/m_random.c | 106 +++++++++++++++++++++++++++++++++---------------- src/m_random.h | 14 ++++--- src/st_stuff.c | 6 ++- 3 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/m_random.c b/src/m_random.c index fce65b88a..eab45a3ed 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -10,7 +10,7 @@ // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file m_random.c -/// \brief LCG PRNG originally created for XMOD +/// \brief RNG for client effects and PRNG for game actions #include "doomdef.h" #include "doomtype.h" @@ -42,7 +42,7 @@ UINT8 M_Random(void) */ INT32 M_SignedRandom(void) { - return M_Random() - 128; + return (rand() & 255) - 128; } /** Provides a random number in between 0 and the given number - 1. @@ -80,12 +80,29 @@ static UINT32 randomseed = 0; static UINT32 initialseed = 0; /** - * Provides a random byte and sets the seed appropriately. - * The nature of this PRNG allows it to cycle through about two million numbers - * before it finally starts repeating numeric sequences. - * That's more than good enough for our purposes. + * Provides a random fixed point number. + * This is a variant of an xorshift PRNG; state fits in a 32 bit integer structure. * - * \return A random byte, 0 to 255. + * \return A random fixed point number from [0,1). + */ +ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void) +{ + randomseed += 7069; + randomseed ^= randomseed << 17; + randomseed ^= randomseed >> 9; + randomseed *= 373; + randomseed ^= randomseed << 21; + randomseed ^= randomseed >> 15; + return (randomseed&((FRACUNIT-1)<<9))>>9; +} + +/** Provides a random integer from 0 to 255. + * Distribution is uniform. + * If you're curious, (&0xFF00) >> 8 gives the same result + * as a fixed point multiplication by 256. + * + * \return Random integer from [0, 255]. + * \sa __internal_prng__ */ #ifndef DEBUGRANDOM UINT8 P_Random(void) @@ -95,15 +112,14 @@ UINT8 P_RandomD(const char *rfile, INT32 rline) { CONS_Printf("P_Random() at: %sp %d\n", rfile, rline); #endif - randomseed = (randomseed*746151647)+48205429; - return (UINT8)((randomseed >> 17)&255); + return (UINT8)((__internal_prng__()&0xFF00)>>8); } -/** Provides a random number from -128 to 127. +/** Provides a random integer from -128 to 127. * Distribution is uniform. * - * \return Random number from -128 to 127. - * \sa P_Random + * \return Random integer from [-128, 127]. + * \sa __internal_prng__ */ #ifndef DEBUGRANDOM INT32 P_SignedRandom(void) @@ -113,15 +129,31 @@ INT32 P_SignedRandomD(const char *rfile, INT32 rline) { CONS_Printf("P_SignedRandom() at: %sp %d\n", rfile, rline); #endif - return P_Random() - 128; + return (INT32)((__internal_prng__()&0xFF00)>>8) - 128; } -/** Provides a random number in between 0 and the given number - 1. - * Distribution is uniform, also calls for two numbers for bigger output range. - * Use for picking random elements from an array. +/** + * Provides a random fixed point number. + * Literally a wrapper for the internal PRNG function. * - * \return A random number, 0 to arg1-1. - * \sa P_Random + * \return A random fixed point number from [0,1). + */ +#ifndef DEBUGRANDOM +fixed_t P_RandomFixed(void) +{ +#else +UINT8 P_RandomFixedD(const char *rfile, INT32 rline) +{ + CONS_Printf("P_Random() at: %sp %d\n", rfile, rline); +#endif + return __internal_prng__(); +} + +/** Provides a random integer for picking random elements from an array. + * Distribution is uniform. + * + * \return A random integer from [0,a). + * \sa __internal_prng__ */ #ifndef DEBUGRANDOM INT32 P_RandomKey(INT32 a) @@ -131,16 +163,14 @@ INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a) { CONS_Printf("P_RandomKey() at: %sp %d\n", rfile, rline); #endif - INT32 prandom = P_Random(); // note: forcing explicit function call order - prandom |= P_Random() << 8; // (function call order is not strictly defined) - return (INT32)((prandom/65536.0f)*a); + return (INT32)((__internal_prng__() * a) >> FRACBITS); } -/** Provides a random number in between a specific range. - * Distribution is uniform, also calls for two numbers for bigger output range. +/** Provides a random integer in a given range. + * Distribution is uniform. * - * \return A random number, arg1 to arg2. - * \sa P_Random + * \return A random integer from [a,b].P_Random + * \sa __internal_prng__ */ #ifndef DEBUGRANDOM INT32 P_RandomRange(INT32 a, INT32 b) @@ -150,21 +180,27 @@ INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b) { CONS_Printf("P_RandomRange() at: %sp %d\n", rfile, rline); #endif - INT32 prandom = P_Random(); // note: forcing explicit function call order - prandom |= P_Random() << 8; // (function call order is not strictly defined) - return (INT32)((prandom/65536.0f)*(b-a+1))+a; + return (INT32)((__internal_prng__() * (b-a+1)) >> FRACBITS) + a; } -/** Provides a random byte without saving what the seed would be. - * Used just to debug the PRNG. + + +// ---------------------- +// PRNG seeds & debugging +// ---------------------- + +/** Peeks to see what the next result from the PRNG will be. + * Used for debugging. * - * \return A 'random' byte, 0 to 255. - * \sa P_Random + * \return A 'random' fixed point number from [0,1). + * \sa __internal_prng__ */ -UINT8 P_RandomPeek(void) +fixed_t P_RandomPeek(void) { - UINT32 r = (randomseed*746151647)+48205429; - return (UINT8)((r >> 17)&255); + UINT32 r = randomseed; + fixed_t ret = __internal_prng__(); + randomseed = r; + return ret; } /** Gets the current random seed. Used by netgame savegames. diff --git a/src/m_random.h b/src/m_random.h index 42c871608..91348365b 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -20,8 +20,9 @@ //#define DEBUGRANDOM + // M_Random functions pull random numbers of various types that aren't network synced. -// P_Random functions pulls random bytes from a LCG PRNG that is network synced. +// P_Random functions pulls random bytes from a PRNG that is network synced. // RNG functions UINT8 M_Random(void); @@ -31,21 +32,24 @@ INT32 M_RandomRange(INT32 a, INT32 b); // PRNG functions #ifdef DEBUGRANDOM -#define P_Random() P_RandomD(__FILE__, __LINE__) -#define P_SignedRandom() P_SignedRandomD(__FILE__, __LINE__) -#define P_RandomKey(c) P_RandomKeyD(__FILE__, __LINE__, c) +#define P_Random() P_RandomD(__FILE__, __LINE__) +#define P_SignedRandom() P_SignedRandomD(__FILE__, __LINE__) +#define P_RandomFixed() P_RandomFixedD(__FILE__, __LINE__) +#define P_RandomKey(c) P_RandomKeyD(__FILE__, __LINE__, c) #define P_RandomRange(c, d) P_RandomRangeD(__FILE__, __LINE__, c, d) UINT8 P_RandomD(const char *rfile, INT32 rline); INT32 P_SignedRandomD(const char *rfile, INT32 rline); +fixed_t P_RandomFixedD(const char *rfile, INT32 rline); INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a); INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b); #else UINT8 P_Random(void); INT32 P_SignedRandom(void); +fixed_t P_RandomFixed(void); INT32 P_RandomKey(INT32 a); INT32 P_RandomRange(INT32 a, INT32 b); #endif -UINT8 P_RandomPeek(void); +fixed_t P_RandomPeek(void); // Working with the seed for PRNG #ifdef DEBUGRANDOM diff --git a/src/st_stuff.c b/src/st_stuff.c index 585db0c87..47eac22f4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -592,9 +592,13 @@ static void ST_drawDebugInfo(void) if (cv_debug & DBG_RANDOMIZER) // randomizer testing { + fixed_t peekres = P_RandomPeek(); + peekres *= 10000; // Change from fixed point + peekres >>= FRACBITS; // to displayable decimal + V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Init: %08x", P_GetInitSeed())); V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Seed: %08x", P_GetRandSeed())); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : %8d", P_RandomPeek())); + V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : .%04d", peekres)); height -= 32; } From ac03ce39c8d681d915ecb1809ce9651aab5a91da Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Sun, 27 Mar 2016 07:33:15 -0700 Subject: [PATCH 23/51] *_Random is now *_RandomByte. P_RandomChance is now a macro for something that should happen a certain percentage of time. P_SignedRandom was moved to a macro. Nobody cared. # Conflicts: # src/p_inter.c --- src/d_netcmd.c | 6 +- src/g_game.c | 10 +-- src/hardware/hw3sound.c | 6 +- src/hardware/hw_light.c | 4 +- src/lua_baselib.c | 39 ++++++++++-- src/m_cheat.c | 6 +- src/m_random.c | 110 +++++++++++++++------------------ src/m_random.h | 34 ++++++----- src/p_enemy.c | 132 +++++++++++++++++++--------------------- src/p_inter.c | 28 +++------ src/p_lights.c | 4 +- src/p_mobj.c | 70 ++++++++++----------- src/p_spec.c | 2 +- src/p_tick.c | 4 +- src/p_user.c | 10 +-- src/v_video.c | 2 +- 16 files changed, 233 insertions(+), 234 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5eb352834..c62ff8fe1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -808,7 +808,7 @@ static boolean IsNameGood(char *name, INT32 playernum) else if (len == 1) // Agh! { // Last ditch effort... - sprintf(name, "%d", M_Random() & 7); + sprintf(name, "%d", M_RandomKey(10)); if (!IsNameGood (name, playernum)) return false; } @@ -3583,7 +3583,7 @@ retryscramble: for (i = 0; i < playercount; i++) { if (repick) - newteam = (INT16)((M_Random() % 2) + 1); + newteam = (INT16)((M_RandomByte() % 2) + 1); // One team has the most players they can get, assign the rest to the other team. if (red == maxcomposition || blue == maxcomposition) @@ -3628,7 +3628,7 @@ retryscramble: { if (repick) { - newteam = (INT16)((M_Random() % 2) + 1); + newteam = (INT16)((M_RandomByte() % 2) + 1); repick = false; } else diff --git a/src/g_game.c b/src/g_game.c index 3b7ef158f..71171fd74 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2331,8 +2331,8 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) } } P_MovePlayerToSpawn(playernum, spawnpoint); - -#ifdef HAVE_BLUA + +#ifdef HAVE_BLUA LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :) #endif @@ -2349,7 +2349,7 @@ mapthing_t *G_FindCTFStart(INT32 playernum) return NULL; } - if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_Random() & 1)) || players[playernum].ctfteam == 1) //red + if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_RandomChance(FRACUNIT/2))) || players[playernum].ctfteam == 1) //red { if (!numredctfstarts) { @@ -5487,7 +5487,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void) UINT8 i; WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker for (i = 0; i < 16; i++, p++) - *p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. #else WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. @@ -5569,7 +5569,7 @@ boolean G_CheckDemoStatus(void) UINT8 i; WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker for (i = 0; i < 16; i++, p++) - *p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. #else WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. diff --git a/src/hardware/hw3sound.c b/src/hardware/hw3sound.c index efc1d247b..c68430921 100644 --- a/src/hardware/hw3sound.c +++ b/src/hardware/hw3sound.c @@ -384,12 +384,12 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan /*if (gamemode != heretic) { if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit) - pitch += 8 - (M_Random()&15); + pitch += 8 - (M_RandomByte()&15); else if (sfx_id != sfx_itemup && sfx_id != sfx_tink) - pitch += 16 - (M_Random()&31); + pitch += 16 - (M_RandomByte()&31); } else*/ - pitch = 128 + (M_Random() & 7) - (M_Random() & 7); + pitch = 128 + (M_RandomByte() & 7) - (M_RandomByte() & 7); } #endif diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index fb369387f..a93e96dc3 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -871,7 +871,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr) size = p_lspr->corona_radius * ((outVerts[0].z+120.0f)/950.0f); // d'ou vienne ces constante ? break; case ROCKET_SPR: - p_lspr->corona_color = (((M_Random()>>1)&0xff)<<24)|0x0040ff; + p_lspr->corona_color = (((M_RandomByte()>>1)&0xff)<<24)|0x0040ff; // don't need a break case CORONA_SPR: size = p_lspr->corona_radius * ((outVerts[0].z+60.0f)/100.0f); // d'ou vienne ces constante ? @@ -974,7 +974,7 @@ void HWR_DrawCoronas(void) size = p_lspr->corona_radius * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ? break; case ROCKET_SPR: - Surf.FlatColor.s.alpha = (UINT8)((M_Random()>>1)&0xff); + Surf.FlatColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff); // don't need a break case CORONA_SPR: size = p_lspr->corona_radius * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ? diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 2cc79db47..45f18627e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -96,17 +96,17 @@ static int lib_evalMath(lua_State *L) // M_RANDOM ////////////// -static int lib_pRandom(lua_State *L) +static int lib_pRandomFixed(lua_State *L) { NOHUD - lua_pushinteger(L, P_Random()); + lua_pushfixed(L, P_RandomFixed()); return 1; } -static int lib_pSignedRandom(lua_State *L) +static int lib_pRandomByte(lua_State *L) { NOHUD - lua_pushinteger(L, P_SignedRandom()); + lua_pushinteger(L, P_RandomByte()); return 1; } @@ -134,6 +134,30 @@ static int lib_pRandomRange(lua_State *L) return 1; } +// Deprecated, macros, etc. +static int lib_pRandom(lua_State *L) +{ + NOHUD + LUA_Deprecated(L, "P_Random", "P_RandomByte"); + lua_pushinteger(L, P_RandomByte()); + return 1; +} + +static int lib_pSignedRandom(lua_State *L) +{ + NOHUD + lua_pushinteger(L, P_SignedRandom()); + return 1; +} + +static int lib_pRandomChance(lua_State *L) +{ + fixed_t p = luaL_checkfixed(L, 1); + NOHUD + lua_pushboolean(L, P_RandomChance(p)); + return 1; +} + // P_MAPUTIL /////////////// @@ -1910,10 +1934,13 @@ static luaL_Reg lib[] = { {"EvalMath", lib_evalMath}, // m_random - {"P_Random",lib_pRandom}, - {"P_SignedRandom",lib_pSignedRandom}, + {"P_RandomFixed",lib_pRandomFixed}, + {"P_RandomByte",lib_pRandomByte}, {"P_RandomKey",lib_pRandomKey}, {"P_RandomRange",lib_pRandomRange}, + {"P_Random",lib_pRandom}, // DEPRECATED + {"P_SignedRandom",lib_pSignedRandom}, // MACRO + {"P_RandomChance",lib_pRandomChance}, // MACRO // p_maputil {"P_AproxDistance",lib_pAproxDistance}, diff --git a/src/m_cheat.c b/src/m_cheat.c index 473fbbf75..6ed8d286a 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -618,9 +618,9 @@ void Command_CauseCfail_f(void) } P_UnsetThingPosition(players[consoleplayer].mo); - P_Random(); - P_Random(); - P_Random(); + P_RandomFixed(); + P_RandomByte(); + P_RandomFixed(); players[consoleplayer].mo->x = 0; players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye players[consoleplayer].mo->z = 123311; diff --git a/src/m_random.c b/src/m_random.c index eab45a3ed..caf4d5174 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -19,48 +19,51 @@ #include "m_random.h" #include "m_fixed.h" + + // --------------------------- // RNG functions (not synched) // --------------------------- -/** Provides a random byte. - * Used outside the p_xxx game code and not synchronized in netgames. This is - * for anything that doesn't need to be synced, e.g. precipitation. +/** Provides a random fixed point number. Distribution is uniform. + * As with all M_Random functions, not synched in netgames. * - * \return A random byte, 0 to 255. + * \return A random fixed point number from [0,1). */ -UINT8 M_Random(void) +fixed_t M_RandomFixed(void) { - return (rand() & 255); + return (rand() & 0xFFFF); } -/** Provides a random signed byte. Distribution is uniform. - * As with all M_*Random functions, not synched in netgames. +/** Provides a random byte. Distribution is uniform. + * As with all M_Random functions, not synched in netgames. * - * \return A random byte, -128 to 127. - * \sa M_Random + * \return A random integer from [0, 255]. */ -INT32 M_SignedRandom(void) +UINT8 M_RandomByte(void) { - return (rand() & 255) - 128; + return (rand() & 0xFF); } -/** Provides a random number in between 0 and the given number - 1. - * Distribution is uniform. Use for picking random elements from an array. - * As with all M_*Random functions, not synched in netgames. +/** Provides a random integer for picking random elements from an array. + * Distribution is uniform. + * As with all M_Random functions, not synched in netgames. * - * \return A random number, 0 to arg1-1. + * \param a Number of items in array. + * \return A random integer from [0,a). */ INT32 M_RandomKey(INT32 a) { return (INT32)((rand()/((unsigned)RAND_MAX+1.0f))*a); } -/** Provides a random number in between a specific range. +/** Provides a random integer in a given range. * Distribution is uniform. - * As with all M_*Random functions, not synched in netgames. + * As with all M_Random functions, not synched in netgames. * - * \return A random number, arg1 to arg2. + * \param a Lower bound. + * \param b Upper bound. + * \return A random integer from [a,b]. */ INT32 M_RandomRange(INT32 a, INT32 b) { @@ -79,8 +82,7 @@ static UINT32 randomseed = 0; // Holds the INITIAL seed value. Used for demos, possibly other debugging. static UINT32 initialseed = 0; -/** - * Provides a random fixed point number. +/** Provides a random fixed point number. * This is a variant of an xorshift PRNG; state fits in a 32 bit integer structure. * * \return A random fixed point number from [0,1). @@ -96,44 +98,7 @@ ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void) return (randomseed&((FRACUNIT-1)<<9))>>9; } -/** Provides a random integer from 0 to 255. - * Distribution is uniform. - * If you're curious, (&0xFF00) >> 8 gives the same result - * as a fixed point multiplication by 256. - * - * \return Random integer from [0, 255]. - * \sa __internal_prng__ - */ -#ifndef DEBUGRANDOM -UINT8 P_Random(void) -{ -#else -UINT8 P_RandomD(const char *rfile, INT32 rline) -{ - CONS_Printf("P_Random() at: %sp %d\n", rfile, rline); -#endif - return (UINT8)((__internal_prng__()&0xFF00)>>8); -} - -/** Provides a random integer from -128 to 127. - * Distribution is uniform. - * - * \return Random integer from [-128, 127]. - * \sa __internal_prng__ - */ -#ifndef DEBUGRANDOM -INT32 P_SignedRandom(void) -{ -#else -INT32 P_SignedRandomD(const char *rfile, INT32 rline) -{ - CONS_Printf("P_SignedRandom() at: %sp %d\n", rfile, rline); -#endif - return (INT32)((__internal_prng__()&0xFF00)>>8) - 128; -} - -/** - * Provides a random fixed point number. +/** Provides a random fixed point number. Distribution is uniform. * Literally a wrapper for the internal PRNG function. * * \return A random fixed point number from [0,1). @@ -144,14 +109,34 @@ fixed_t P_RandomFixed(void) #else UINT8 P_RandomFixedD(const char *rfile, INT32 rline) { - CONS_Printf("P_Random() at: %sp %d\n", rfile, rline); + CONS_Printf("P_RandomFixed() at: %sp %d\n", rfile, rline); #endif return __internal_prng__(); } +/** Provides a random byte. Distribution is uniform. + * If you're curious, (&0xFF00) >> 8 gives the same result + * as a fixed point multiplication by 256. + * + * \return Random integer from [0, 255]. + * \sa __internal_prng__ + */ +#ifndef DEBUGRANDOM +UINT8 P_RandomByte(void) +{ +#else +UINT8 P_RandomByteD(const char *rfile, INT32 rline) +{ + CONS_Printf("P_RandomByte() at: %sp %d\n", rfile, rline); +#endif + return (UINT8)((__internal_prng__()&0xFF00)>>8); +} + /** Provides a random integer for picking random elements from an array. * Distribution is uniform. + * NOTE: Maximum range is 65536. * + * \param a Number of items in array. * \return A random integer from [0,a). * \sa __internal_prng__ */ @@ -168,8 +153,11 @@ INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a) /** Provides a random integer in a given range. * Distribution is uniform. + * NOTE: Maximum range is 65536. * - * \return A random integer from [a,b].P_Random + * \param a Lower bound. + * \param b Upper bound. + * \return A random integer from [a,b]. * \sa __internal_prng__ */ #ifndef DEBUGRANDOM diff --git a/src/m_random.h b/src/m_random.h index 91348365b..90784a5d0 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -25,30 +25,36 @@ // P_Random functions pulls random bytes from a PRNG that is network synced. // RNG functions -UINT8 M_Random(void); -INT32 M_SignedRandom(void); -INT32 M_RandomKey(INT32 a); -INT32 M_RandomRange(INT32 a, INT32 b); +fixed_t M_RandomFixed(void); +UINT8 M_RandomByte(void); +INT32 M_RandomKey(INT32 a); +INT32 M_RandomRange(INT32 a, INT32 b); // PRNG functions #ifdef DEBUGRANDOM -#define P_Random() P_RandomD(__FILE__, __LINE__) -#define P_SignedRandom() P_SignedRandomD(__FILE__, __LINE__) #define P_RandomFixed() P_RandomFixedD(__FILE__, __LINE__) +#define P_RandomByte() P_RandomByteD(__FILE__, __LINE__) #define P_RandomKey(c) P_RandomKeyD(__FILE__, __LINE__, c) #define P_RandomRange(c, d) P_RandomRangeD(__FILE__, __LINE__, c, d) -UINT8 P_RandomD(const char *rfile, INT32 rline); -INT32 P_SignedRandomD(const char *rfile, INT32 rline); fixed_t P_RandomFixedD(const char *rfile, INT32 rline); -INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a); -INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b); +UINT8 P_RandomByteD(const char *rfile, INT32 rline); +INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a); +INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b); #else -UINT8 P_Random(void); -INT32 P_SignedRandom(void); fixed_t P_RandomFixed(void); -INT32 P_RandomKey(INT32 a); -INT32 P_RandomRange(INT32 a, INT32 b); +UINT8 P_RandomByte(void); +INT32 P_RandomKey(INT32 a); +INT32 P_RandomRange(INT32 a, INT32 b); #endif + +// Macros for other functions +#define M_SignedRandom() ((INT32)M_RandomByte() - 128) // [-128, 127] signed byte, originally a +#define P_SignedRandom() ((INT32)P_RandomByte() - 128) // function of its own, moved to a macro + +#define M_RandomChance(p) (M_RandomFixed() < p) // given fixed point probability, p, between 0 (0%) +#define P_RandomChance(p) (P_RandomFixed() < p) // and FRACUNIT (100%), returns true p% of the time + +// Debugging fixed_t P_RandomPeek(void); // Working with the seed for PRNG diff --git a/src/p_enemy.c b/src/p_enemy.c index 367d5714a..b8737810c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -386,7 +386,7 @@ boolean P_CheckMissileRange(mobj_t *actor) if (actor->type == MT_EGGMOBILE && dist > 160) dist = 160; - if (P_Random() < dist) + if (P_RandomByte() < dist) return false; return true; @@ -486,7 +486,7 @@ static boolean P_TryWalk(mobj_t *actor) { if (!P_Move(actor, actor->info->speed)) return false; - actor->movecount = P_Random() & 15; + actor->movecount = P_RandomByte() & 15; return true; } @@ -539,7 +539,7 @@ void P_NewChaseDir(mobj_t *actor) } // try other directions - if (P_Random() > 200 || abs(deltay) > abs(deltax)) + if (P_RandomChance(25*FRACUNIT/32) || abs(deltay) > abs(deltax)) { tdir = d[1]; d[1] = d[2]; @@ -577,7 +577,7 @@ void P_NewChaseDir(mobj_t *actor) } // randomly determine direction of search - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) { for (tdir = DI_EAST; tdir <= DI_SOUTHEAST; tdir++) { @@ -632,7 +632,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed // BP: first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook %= MAXPLAYERS; @@ -707,7 +707,7 @@ static boolean P_LookForShield(mobj_t *actor) // BP: first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook %= MAXPLAYERS; @@ -2293,12 +2293,7 @@ void A_SkullAttack(mobj_t *actor) if (locvar1 == 1) actor->angle += ANGLE_180; else if (locvar1 == 2) - { - if (P_Random() & 1) - actor->angle += ANGLE_90; - else - actor->angle -= ANGLE_90; - } + actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90; an = actor->angle >> ANGLETOFINESHIFT; @@ -2398,9 +2393,9 @@ void A_BossScream(mobj_t *actor) explodetype = (mobjtype_t)locvar2; if (actor->eflags & MFE_VERTICALFLIP) - z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); + z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); else - z = actor->z + FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); + z = actor->z + FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); mo = P_SpawnMobj(x, y, z, explodetype); if (actor->eflags & MFE_VERTICALFLIP) @@ -3461,7 +3456,7 @@ void A_BubbleSpawn(mobj_t *actor) return; // don't make bubble! } - prandom = P_Random(); + prandom = P_RandomByte(); if (leveltime % (3*TICRATE) < 8) bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_EXTRALARGEBUBBLE); @@ -3509,7 +3504,7 @@ void A_FanBubbleSpawn(mobj_t *actor) return; // don't make bubble! } - prandom = P_Random(); + prandom = P_RandomByte(); if ((prandom & 0x7) == 0x7) bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_SMALLBUBBLE); @@ -3550,7 +3545,7 @@ void A_BubbleRise(mobj_t *actor) // Move around slightly to make it look like it's bending around the water if (!locvar1) { - UINT8 prandom = P_Random(); + UINT8 prandom = P_RandomByte(); if (!(prandom & 0x7)) // *****000 { P_InstaThrust(actor, prandom & 0x70 ? actor->angle + ANGLE_90 : actor->angle, @@ -3833,7 +3828,7 @@ void A_ThrownRing(mobj_t *actor) // first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook %= MAXPLAYERS; @@ -3913,7 +3908,7 @@ void A_SetSolidSteam(mobj_t *actor) #endif actor->flags &= ~MF_NOCLIP; actor->flags |= MF_SOLID; - if (!(P_Random() & 7)) + if (P_RandomChance(FRACUNIT/8)) { if (actor->info->deathsound) S_StartSound(actor, actor->info->deathsound); // Hiss! @@ -4055,7 +4050,7 @@ void A_JetChase(mobj_t *actor) if (actor->reactiontime) actor->reactiontime--; - if (P_Random() % 32 == 1) + if (P_RandomChance(FRACUNIT/32)) { actor->momx = actor->momx / 2; actor->momy = actor->momy / 2; @@ -4416,7 +4411,7 @@ void A_JetgThink(mobj_t *actor) if (actor->target) { - if (P_Random() <= 32 && !actor->reactiontime) + if (P_RandomChance(FRACUNIT/8) && !actor->reactiontime) P_SetMobjState(actor, actor->info->missilestate); else A_JetChase (actor); @@ -4469,10 +4464,10 @@ void A_MouseThink(mobj_t *actor) { if (twodlevel || actor->flags2 & MF2_TWOD) { - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) actor->angle += ANGLE_180; } - else if (P_Random() & 1) + else if (P_RandomChance(FRACUNIT/2)) actor->angle += ANGLE_90; else actor->angle -= ANGLE_90; @@ -4878,7 +4873,7 @@ void A_RockSpawn(mobj_t *actor) type = MT_ROCKCRUMBLE1 + (sides[line->sidenum[0]].rowoffset >> FRACBITS); if (line->flags & ML_NOCLIMB) - randomoomph = P_Random() * (FRACUNIT/32); + randomoomph = P_RandomByte() * (FRACUNIT/32); else randomoomph = 0; @@ -5172,7 +5167,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) if (locvar1) { - if (actor->health < 2 && P_Random() < 2) + if (actor->health < 2 && P_RandomChance(FRACUNIT/128)) P_SpawnMissile(actor, actor->target, locvar1); } @@ -5187,8 +5182,8 @@ void A_CrawlaCommanderThink(mobj_t *actor) actor->threshold = 0; // Roam around, somewhat in the player's direction. - actor->angle += (P_Random()<<10); - actor->angle -= (P_Random()<<10); + actor->angle += (P_RandomByte()<<10); + actor->angle -= (P_RandomByte()<<10); if (actor->health > 1) P_InstaThrust(actor, actor->angle, FixedMul(10*FRACUNIT, actor->scale)); @@ -5204,7 +5199,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) actor->threshold = 1; } } - actor->reactiontime = 2*TICRATE + P_Random()/2; + actor->reactiontime = 2*TICRATE + P_RandomByte()/2; } if (actor->health == 1) @@ -5222,8 +5217,8 @@ void A_CrawlaCommanderThink(mobj_t *actor) } else { - UINT8 prandom = P_Random(); - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); + UINT8 prandom = P_RandomByte(); + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); P_InstaThrust(actor, actor->angle, FixedDiv(FixedMul(locvar2, actor->scale), 3*FRACUNIT/2)); actor->momz = FixedMul(locvar2, actor->scale); // Bounce up in air } @@ -5552,7 +5547,7 @@ void A_MixUp(mobj_t *actor) { if (counter > 255) // fail-safe to avoid endless loop break; - prandom = P_Random(); + prandom = P_RandomByte(); prandom %= numplayers; // I love modular arithmetic, don't you? if (prandom) // Make sure it's not a useless mix break; @@ -5701,7 +5696,7 @@ void A_RecyclePowers(mobj_t *actor) { UINT8 tempint; - i = j + ((P_Random() + leveltime) % (numplayers - j)); + i = j + ((P_RandomByte() + leveltime) % (numplayers - j)); tempint = postscramble[j]; postscramble[j] = postscramble[i]; postscramble[i] = tempint; @@ -5814,7 +5809,7 @@ void A_Boss1Chase(mobj_t *actor) { if (actor->health > actor->info->damage) { - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) P_SetMobjState(actor, actor->info->missilestate); else P_SetMobjState(actor, actor->info->meleestate); @@ -5833,7 +5828,7 @@ void A_Boss1Chase(mobj_t *actor) // ? nomissile: // possibly choose another target - if (multiplayer && P_Random() < 2) + if (multiplayer && P_RandomChance(FRACUNIT/128)) { if (P_LookForPlayers(actor, true, false, 0)) return; // got a new target @@ -5871,7 +5866,7 @@ nomissile: deltay = actor->target->y - actor->y; actor->movedir = diags[((deltay < 0)<<1) + (deltax > 0)]; - actor->movecount = P_Random() & 15; + actor->movecount = P_RandomByte() & 15; } } @@ -5897,13 +5892,13 @@ void A_Boss2Chase(mobj_t *actor) // Startup randomness if (actor->reactiontime <= -666) - actor->reactiontime = 2*TICRATE + P_Random(); + actor->reactiontime = 2*TICRATE + P_RandomByte(); // When reactiontime hits zero, he will go the other way if (--actor->reactiontime <= 0) { reverse = true; - actor->reactiontime = 2*TICRATE + P_Random(); + actor->reactiontime = 2*TICRATE + P_RandomByte(); } P_SetTarget(&actor->target, P_GetClosestAxis(actor)); @@ -5990,12 +5985,12 @@ void A_Boss2Chase(mobj_t *actor) if (actor->info->attacksound) S_StartAttackSound(actor, actor->info->attacksound); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) { goop->momx *= 2; goop->momy *= 2; } - else if (P_Random() > 128) + else if (P_RandomChance(129*FRACUNIT/256)) { goop->momx *= 3; goop->momy *= 3; @@ -6153,7 +6148,7 @@ void A_Boss7Chase(mobj_t *actor) { A_FaceTarget(actor); P_SetMobjState(actor, S_BLACKEGG_SHOOT1); - actor->movecount = TICRATE + P_Random()/2; + actor->movecount = TICRATE + P_RandomByte()/2; return; } @@ -6162,7 +6157,7 @@ void A_Boss7Chase(mobj_t *actor) if (actor->reactiontime <= 0 && actor->z == actor->floorz) { - // Here, we'll call P_Random() and decide what kind of attack to do + // Here, we'll call P_RandomByte() and decide what kind of attack to do switch(actor->threshold) { case 0: // Lob cannon balls @@ -6170,7 +6165,7 @@ void A_Boss7Chase(mobj_t *actor) { A_FaceTarget(actor); P_SetMobjState(actor, actor->info->xdeathstate); - actor->movecount = 7*TICRATE + P_Random(); + actor->movecount = 7*TICRATE + P_RandomByte(); break; } actor->threshold++; @@ -6180,9 +6175,9 @@ void A_Boss7Chase(mobj_t *actor) P_SetMobjState(actor, S_BLACKEGG_SHOOT1); if (actor->health > actor->info->damage) - actor->movecount = TICRATE + P_Random()/3; + actor->movecount = TICRATE + P_RandomByte()/3; else - actor->movecount = TICRATE + P_Random()/2; + actor->movecount = TICRATE + P_RandomByte()/2; break; case 2: // Homing Missile A_FaceTarget(actor); @@ -6266,8 +6261,8 @@ void A_Boss2PogoSFX(mobj_t *actor) } else { - UINT8 prandom = P_Random(); - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); + UINT8 prandom = P_RandomByte(); + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); } if (actor->info->activesound) S_StartSound(actor, actor->info->activesound); @@ -6307,10 +6302,10 @@ void A_Boss2PogoTarget(mobj_t *actor) // Target hit, retreat! if (actor->target->player->powers[pw_flashing] > TICRATE || actor->flags2 & MF2_FRET) { - UINT8 prandom = P_Random(); + UINT8 prandom = P_RandomByte(); actor->z++; // unstick from the floor actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it. + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it. P_InstaThrust(actor, actor->angle+ANGLE_180, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed } // Try to land on top of the player. @@ -6347,10 +6342,10 @@ void A_Boss2PogoTarget(mobj_t *actor) // Wander semi-randomly towards the player to get closer. else { - UINT8 prandom = P_Random(); + UINT8 prandom = P_RandomByte(); actor->z++; // unstick from the floor actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it. + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it. P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed } // Boing! @@ -7084,7 +7079,7 @@ void A_SmokeTrailer(mobj_t *actor) P_SetObjectMomZ(th, FRACUNIT, false); th->destscale = actor->scale; P_SetScale(th, actor->scale); - th->tics -= P_Random() & 3; + th->tics -= P_RandomByte() & 3; if (th->tics < 1) th->tics = 1; } @@ -7183,7 +7178,7 @@ void A_ChangeAngleRelative(mobj_t *actor) // rather than the ranges, so <0 and >360 work as possible values. -Red INT32 locvar1 = var1; INT32 locvar2 = var2; - //angle_t angle = (P_Random()+1)<<24; + //angle_t angle = (P_RandomByte()+1)<<24; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; //const angle_t amin = FixedAngle(locvar1*FRACUNIT); @@ -7217,7 +7212,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - //angle_t angle = (P_Random()+1)<<24; + //angle_t angle = (P_RandomByte()+1)<<24; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; //const angle_t amin = FixedAngle(locvar1*FRACUNIT); @@ -7825,7 +7820,7 @@ void A_RandomState(mobj_t *actor) return; #endif - P_SetMobjState(actor, P_Random()&1 ? locvar1 : locvar2); + P_SetMobjState(actor, P_RandomChance(FRACUNIT/2) ? locvar1 : locvar2); } // Function: A_RandomStateRange @@ -8516,34 +8511,29 @@ void A_SearchForPlayers(mobj_t *actor) // Function: A_CheckRandom // -// Description: Calls a state by chance (around 1/var1). +// Description: Calls a state by chance. // -// var1 = denominator (can't exceed 100) +// var1: +// lower 16 bits = denominator +// upper 16 bits = numerator (defaults to 1 if zero) // var2 = state number // void A_CheckRandom(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - INT32 i, chance; - INT32 rndadd = 0; + fixed_t chance = FRACUNIT; + #ifdef HAVE_BLUA if (LUA_CallAction("A_CheckRandom", actor)) return; #endif + // The PRNG doesn't suck anymore, OK? + if (locvar1 >> 16) + chance *= (locvar1 >> 16); + chance /= (locvar1 & 0xFFFF); - if(locvar1 > 100) - locvar1 = 100; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - rndadd += abs((int)players[i].mo->x) + abs((int)players[i].mo->y) + abs((int)players[i].mo->z); - - rndadd = rndadd % 10000; //additional component to enlarge random number - - chance = (P_Random() + rndadd) % locvar1; - - if (chance == 0) + if (P_RandomChance(chance)) P_SetMobjState(actor, locvar2); } @@ -9890,7 +9880,7 @@ void A_BrakChase(mobj_t *actor) S_StartSound(actor, (sfxenum_t)locvar2); // make active sound - if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_Random() < 3) + if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_RandomChance(3*FRACUNIT/256)) { S_StartSound(actor, actor->info->activesound); } diff --git a/src/p_inter.c b/src/p_inter.c index b8101f12b..128b50721 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1236,7 +1236,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target && special->target->state == &states[S_BLACKEGG_SHOOT1]) { - if (special->target->health <= 2 && (P_Random() & 1)) + if (special->target->health <= 2 && P_RandomChance(FRACUNIT/2)) P_SetMobjState(special->target, special->target->info->missilestate); else P_SetMobjState(special->target, special->target->info->raisestate); @@ -2186,29 +2186,17 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) default: if (target->info->doomednum) + prandom = target->info->doomednum%5; // "Random" animal for new enemies. + else + prandom = P_RandomKey(5); // No placable object, just use a random number. + + switch(prandom) { - switch(target->info->doomednum%5) - { default: item = MT_BUNNY; break; case 1: item = MT_BIRD; break; case 2: item = MT_MOUSE; break; case 3: item = MT_COW; break; case 4: item = MT_CHICKEN; break; - } - } - else - { - prandom = P_Random(); - if (prandom < 51) - item = MT_BUNNY; - else if (prandom < 102) - item = MT_BIRD; - else if (prandom < 153) - item = MT_MOUSE; - else if (prandom < 204) - item = MT_COW; - else - item = MT_CHICKEN; } break; } @@ -3086,7 +3074,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Killing dead. Just for kicks. // Require source and inflictor be player. Don't hurt for firing rings. - if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_Random() < 80) + if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_RandomChance(5*FRACUNIT/16)) P_DamageMobj(source, target, target, 1); // do the damage @@ -3600,7 +3588,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss) P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); else { - angle_t fa = P_Random()*FINEANGLES/256; + angle_t fa = P_RandomByte()*FINEANGLES/256; flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); diff --git a/src/p_lights.c b/src/p_lights.c index 2dfe006dc..a9758c723 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -51,7 +51,7 @@ void T_FireFlicker(fireflicker_t *flick) if (--flick->count) return; - amount = (INT16)((UINT8)(P_Random() & 3) * 16); + amount = (INT16)((UINT8)(P_RandomByte() & 3) * 16); if (flick->sector->lightlevel - amount < flick->minlight) flick->sector->lightlevel = (INT16)flick->minlight; @@ -235,7 +235,7 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, flash->minlight = 0; if (!inSync) - flash->count = (P_Random() & 7) + 1; + flash->count = (P_RandomByte() & 7) + 1; else flash->count = 1; diff --git a/src/p_mobj.c b/src/p_mobj.c index 4e60ad612..150af1e08 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -652,9 +652,9 @@ void P_EmeraldManager(void) break; if (leveltime < TICRATE) // Start of map - spawnpoints[j]->threshold = 60*TICRATE + P_Random() * (TICRATE/5); + spawnpoints[j]->threshold = 60*TICRATE + P_RandomByte() * (TICRATE/5); else - spawnpoints[j]->threshold = P_Random() * (TICRATE/5); + spawnpoints[j]->threshold = P_RandomByte() * (TICRATE/5); break; } @@ -683,26 +683,26 @@ void P_ExplodeMissile(mobj_t *mo) explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_pop); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx += (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_dmpain); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx -= (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy += (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_pop); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_cybdth); // Hack: Release an animal. @@ -2405,12 +2405,12 @@ static boolean P_ZMovement(mobj_t *mo) // If deafed, give the tumbleweed another random kick if it runs out of steam. mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mom.x += FixedMul(6*FRACUNIT, mo->scale); else mom.x -= FixedMul(6*FRACUNIT, mo->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mom.y += FixedMul(6*FRACUNIT, mo->scale); else mom.y -= FixedMul(6*FRACUNIT, mo->scale); @@ -2886,7 +2886,7 @@ static boolean P_SceneryZMovement(mobj_t *mo) for (i = 0; i < 4; ++i) // split into four { - prandom = P_Random(); + prandom = P_RandomByte(); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_SMALLBUBBLE); explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1); explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1); @@ -3218,13 +3218,13 @@ void P_MobjCheckWater(mobj_t *mobj) // Create tons of bubbles for (i = 0; i < bubblecount; i++) { - // P_Random()s are called individually to allow consistency + // P_RandomByte()s are called individually to allow consistency // across various compilers, since the order of function calls // in C is not part of the ANSI specification. - prandom[0] = P_Random(); - prandom[1] = P_Random(); - prandom[2] = P_Random(); - prandom[3] = P_Random(); + prandom[0] = P_RandomByte(); + prandom[1] = P_RandomByte(); + prandom[2] = P_RandomByte(); + prandom[3] = P_RandomByte(); bubbletype = MT_SMALLBUBBLE; if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32 @@ -3826,7 +3826,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) // first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook &= PLAYERSMASK; for( ; ; actor->lastlook = (actor->lastlook+1) & PLAYERSMASK) @@ -4707,7 +4707,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (mobj->state == &states[S_BLACKEGG_STND] && mobj->tics == mobj->state->tics) { - mobj->reactiontime += P_Random(); + mobj->reactiontime += P_RandomByte(); if (mobj->health <= mobj->info->damage) mobj->reactiontime /= 4; @@ -4901,7 +4901,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT && mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum) { - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) waypointNum++; else waypointNum--; @@ -4913,7 +4913,7 @@ static void P_Boss7Thinker(mobj_t *mobj) } if (waypointNum == 0 && mobj->health <= mobj->info->damage) - waypointNum = 1 + (P_Random() & 1); + waypointNum = 1 + (P_RandomFixed() & 1); // scan the thinkers to find // the waypoint to use @@ -5013,7 +5013,7 @@ static void P_Boss7Thinker(mobj_t *mobj) P_SetMobjState(mobj, mobj->info->spawnstate); } else if (mobj->state == &states[mobj->info->deathstate] && mobj->tics == mobj->state->tics) - S_StartSound(0, sfx_bedie1 + (P_Random() & 1)); + S_StartSound(0, sfx_bedie1 + (P_RandomFixed() & 1)); } @@ -5440,7 +5440,7 @@ static void P_Boss9Thinker(mobj_t *mobj) // An incoming attack is detected! What should we do?! // Go into vector form! mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<info->spawnhealth-1)<movedir = InvAngle(mobj->movedir); mobj->threshold = 6 + (FixedMul(24<info->spawnhealth - mobj->health)<info->spawnhealth-1)<>FRACBITS); if (mobj->info->activesound) @@ -6042,20 +6042,20 @@ static void P_KoopaThinker(mobj_t *koopa) P_XYMovement(koopa); - if (P_Random() < 8 && koopa->z <= koopa->floorz) + if (P_RandomChance(FRACUNIT/32) && koopa->z <= koopa->floorz) koopa->momz = FixedMul(5*FRACUNIT, koopa->scale); if (koopa->z > koopa->floorz) koopa->momz += FixedMul(FRACUNIT/4, koopa->scale); - if (P_Random() < 4) + if (P_RandomChance(FRACUNIT/64)) { mobj_t *flame; - flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_Random()<<(FRACBITS-2)), MT_KOOPAFLAME); + flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_RandomByte()<<(FRACBITS-2)), MT_KOOPAFLAME); flame->momx = -FixedMul(flame->info->speed, flame->scale); S_StartSound(flame, sfx_koopfr); } - else if (P_Random() > 250) + else if (P_RandomChance(5*FRACUNIT/256)) { mobj_t *hammer; hammer = P_SpawnMobj(koopa->x - koopa->radius, koopa->y, koopa->z + koopa->height, MT_HAMMER); @@ -6499,11 +6499,11 @@ void P_MobjThinker(mobj_t *mobj) fixed_t ns; mobj_t *mo2; - i = P_Random(); - z = mobj->subsector->sector->floorheight + ((P_Random()&63)*FRACUNIT); + i = P_RandomByte(); + z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT); for (j = 0; j < 2; j++) { - const angle_t fa = (P_Random()*FINEANGLES/16) & FINEMASK; + const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK; ns = 64 * FRACUNIT; x = mobj->x + FixedMul(FINESINE(fa),ns); y = mobj->y + FixedMul(FINECOSINE(fa),ns); @@ -6513,7 +6513,7 @@ void P_MobjThinker(mobj_t *mobj) mo2->momx = FixedMul(FINESINE(fa),ns); mo2->momy = FixedMul(FINECOSINE(fa),ns); - i = P_Random(); + i = P_RandomByte(); if (i % 5 == 0) P_SpawnMobj(x, y, z, MT_CHICKEN); @@ -7997,7 +7997,7 @@ void P_SpawnPrecipitation(void) continue; rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); - mrand = M_Random(); + mrand = M_RandomByte(); if (mrand < 64) P_SetPrecipMobjState(rainmo, S_SNOW3); else if (mrand < 144) @@ -9166,12 +9166,12 @@ ML_NOCLIMB : Direction not controllable { mobj->momz += FixedMul(16*FRACUNIT, mobj->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mobj->momx += FixedMul(16*FRACUNIT, mobj->scale); else mobj->momx -= FixedMul(16*FRACUNIT, mobj->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mobj->momy += FixedMul(16*FRACUNIT, mobj->scale); else mobj->momy -= FixedMul(16*FRACUNIT,mobj->scale); diff --git a/src/p_spec.c b/src/p_spec.c index 277fe19eb..415e1be01 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2057,7 +2057,7 @@ void P_SwitchWeather(INT32 weathernum) precipmobj = (precipmobj_t *)think; precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; - z = M_Random(); + z = M_RandomByte(); if (z < 64) z = 2; diff --git a/src/p_tick.c b/src/p_tick.c index c72ab5b67..d45f58821 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -363,7 +363,7 @@ static void P_DoAutobalanceTeams(void) { if (totalred > totalblue) { - i = M_Random() % red; + i = M_RandomKey(red); NetPacket.packet.newteam = 2; NetPacket.packet.playernum = redarray[i]; NetPacket.packet.verification = true; @@ -375,7 +375,7 @@ static void P_DoAutobalanceTeams(void) if (totalblue > totalred) { - i = M_Random() % blue; + i = M_RandomKey(blue); NetPacket.packet.newteam = 1; NetPacket.packet.playernum = bluearray[i]; NetPacket.packet.verification = true; diff --git a/src/p_user.c b/src/p_user.c index 03b2c1dd8..380ac9804 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2172,9 +2172,9 @@ static void P_DoBubbleBreath(player_t *player) if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator) return; - if (!(P_Random() % 16)) + if (P_RandomChance(FRACUNIT/16)) bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE); - else if (!(P_Random() % 96)) + else if (P_RandomChance(3*FRACUNIT/256)) bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE); if (bubble) { @@ -6620,7 +6620,7 @@ static void P_MovePlayer(player_t *player) // Little water sound while touching water - just a nicety. if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator) { - if (P_Random() & 1 && leveltime % TICRATE == 0) + if (P_RandomChance(FRACUNIT/2) && leveltime % TICRATE == 0) S_StartSound(player->mo, sfx_floush); } @@ -8423,7 +8423,7 @@ static boolean P_SpectatorJoinGame(player_t *player) else if (redscore > bluescore) changeto = 2; else - changeto = (P_Random() & 1) + 1; + changeto = (P_RandomFixed() & 1) + 1; if (player->mo) { @@ -8674,7 +8674,7 @@ void P_PlayerThink(player_t *player) // Add some extra randomization. if (cmd->forwardmove) - P_Random(); + P_RandomFixed(); #ifdef PARANOIA if (player->playerstate == PST_REBORN) diff --git a/src/v_video.c b/src/v_video.c index df81ac6d6..02c67a24e 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1967,7 +1967,7 @@ Unoptimized version for (y = 0; y < height; y++) { - if (M_Random() < 32) + if (M_RandomChance(FRACUNIT/8)) // 12.5% heatshifter[y] = true; } From a3e940fe65a85b3423b6918b21b795e962fdd63d Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Sun, 27 Mar 2016 15:57:50 -0700 Subject: [PATCH 24/51] Compensate for insufficient RAND_MAX values. --- src/m_random.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/m_random.c b/src/m_random.c index caf4d5174..97b654c1c 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -32,7 +32,13 @@ */ fixed_t M_RandomFixed(void) { +#if RAND_MAX < 65535 + // Compensate for insufficient randomness. + fixed_t rndv = (rand()&1)<<15; + return rand()^rndv; +#else return (rand() & 0xFFFF); +#endif } /** Provides a random byte. Distribution is uniform. @@ -246,5 +252,5 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed) */ UINT32 M_RandomizedSeed(void) { - return ((totalplaytime & 0xFFFF) << 16)|(rand() & 0xFFFF); + return ((totalplaytime & 0xFFFF) << 16)|M_RandomFixed(); } From 3dc4cfc2290e99f0c77f8b661d04c9e6a8669ca6 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Tue, 29 Mar 2016 06:14:31 -0700 Subject: [PATCH 25/51] Simplicity is a virute... don't overcomplicate things. --- src/m_random.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/m_random.c b/src/m_random.c index 97b654c1c..d3d3f98ca 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -95,13 +95,10 @@ static UINT32 initialseed = 0; */ ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void) { - randomseed += 7069; - randomseed ^= randomseed << 17; - randomseed ^= randomseed >> 9; - randomseed *= 373; + randomseed ^= randomseed >> 13; + randomseed ^= randomseed >> 11; randomseed ^= randomseed << 21; - randomseed ^= randomseed >> 15; - return (randomseed&((FRACUNIT-1)<<9))>>9; + return ( (randomseed*36548569) >> 4) & (FRACUNIT-1); } /** Provides a random fixed point number. Distribution is uniform. From 480f9be51f9c38ef0f8ce61fc5c014564cd38b54 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Tue, 29 Mar 2016 06:20:26 -0700 Subject: [PATCH 26/51] gotta start compensating for xorshift's needs --- src/m_random.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/m_random.c b/src/m_random.c index d3d3f98ca..79f3af113 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -83,10 +83,10 @@ INT32 M_RandomRange(INT32 a, INT32 b) // ------------------------ // Holds the current seed. -static UINT32 randomseed = 0; +static UINT32 randomseed = 0xBADE4404; // Holds the INITIAL seed value. Used for demos, possibly other debugging. -static UINT32 initialseed = 0; +static UINT32 initialseed = 0xBADE4404; /** Provides a random fixed point number. * This is a variant of an xorshift PRNG; state fits in a 32 bit integer structure. @@ -240,6 +240,9 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed) { CONS_Printf("P_SetRandSeed() at: %sp %d\n", rfile, rline); #endif + // xorshift requires a nonzero seed + // this should never happen, but just in case it DOES, we check + if (!seed) seed = 0xBADE4404; randomseed = initialseed = seed; } From 9cec9093bb20cbdad7c25da4f4644c7ea1fa3b03 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 30 Mar 2016 06:20:57 -0700 Subject: [PATCH 27/51] denom of A_CheckRandom can't be zero, that would be bad --- src/p_enemy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index c32e2be8c..82391a748 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8528,6 +8528,9 @@ void A_CheckRandom(mobj_t *actor) if (LUA_CallAction("A_CheckRandom", actor)) return; #endif + if ((locvar1 & 0xFFFF) == 0) + return; + // The PRNG doesn't suck anymore, OK? if (locvar1 >> 16) chance *= (locvar1 >> 16); From e34da95c4c2bbfa8e706e52fc764859405eb49ad Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 31 Mar 2016 16:32:25 +0100 Subject: [PATCH 28/51] DEVMODE's automap now supports slopes --- src/am_map.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/am_map.c b/src/am_map.c index 97b7c5164..847e517fb 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -15,6 +15,7 @@ #include "am_map.h" #include "g_input.h" #include "p_local.h" +#include "p_slopes.h" #include "v_video.h" #include "i_video.h" #include "r_state.h" @@ -996,6 +997,10 @@ static inline void AM_drawWalls(void) { size_t i; static mline_t l; +#ifdef ESLOPE + fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends + fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends +#endif for (i = 0; i < numlines; i++) { @@ -1003,6 +1008,22 @@ static inline void AM_drawWalls(void) l.a.y = lines[i].v1->y; l.b.x = lines[i].v2->x; l.b.y = lines[i].v2->y; +#ifdef ESLOPE +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, l.a.x, l.a.y); \ + end2 = P_GetZAt(slope, l.b.x, l.b.y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight) + SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight) + if (lines[i].backsector) { + SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight) + SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight) + } +#undef SLOPEPARAMS +#endif // AM_drawMline(&l, GRAYS + 3); // Old, everything-is-gray automap if (!lines[i].backsector) // 1-sided @@ -1016,11 +1037,19 @@ static inline void AM_drawWalls(void) AM_drawMline(&l, WALLCOLORS+lightlev); } } +#ifdef ESLOPE + else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier + || (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier + { + if (backf1 == backc1 && backf2 == backc2 + && frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers +#else else if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight // Back is thok barrier || lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // Front is thok barrier { if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight && lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // BOTH are thok barriers +#endif { if (lines[i].flags & ML_NOCLIMB) { @@ -1046,12 +1075,20 @@ static inline void AM_drawWalls(void) else { if (lines[i].flags & ML_NOCLIMB) { +#ifdef ESLOPE + if (backf1 != frontf1 || backf2 != frontf2) { +#else if (lines[i].backsector->floorheight != lines[i].frontsector->floorheight) { +#endif AM_drawMline(&l, NOCLIMBFDWALLCOLORS + lightlev); // floor level change } +#ifdef ESLOPE + else if (backc1 != frontc1 || backc2 != frontc2) { +#else else if (lines[i].backsector->ceilingheight != lines[i].frontsector->ceilingheight) { +#endif AM_drawMline(&l, NOCLIMBCDWALLCOLORS+lightlev); // ceiling level change } else { @@ -1060,12 +1097,20 @@ static inline void AM_drawWalls(void) } else { +#ifdef ESLOPE + if (backf1 != frontf1 || backf2 != frontf2) { +#else if (lines[i].backsector->floorheight != lines[i].frontsector->floorheight) { +#endif AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change } +#ifdef ESLOPE + else if (backc1 != frontc1 || backc2 != frontc2) { +#else else if (lines[i].backsector->ceilingheight != lines[i].frontsector->ceilingheight) { +#endif AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change } else { From aab5e656ea4d50e7bf2d8ac521711fcb6511e487 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 2 Apr 2016 17:01:58 +0100 Subject: [PATCH 29/51] removed unused "total" variable in P_GroupLines --- src/p_setup.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a778469fb..f165aa1e2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1888,7 +1888,7 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum) // static void P_GroupLines(void) { - size_t i, j, total = 0; + size_t i, j; line_t *li; sector_t *sector; subsector_t *ss = subsectors; @@ -1922,14 +1922,10 @@ static void P_GroupLines(void) // count number of lines in each sector for (i = 0, li = lines; i < numlines; i++, li++) { - total++; li->frontsector->linecount++; if (li->backsector && li->backsector != li->frontsector) - { li->backsector->linecount++; - total++; - } } // allocate linebuffers for each sector From cf89a5bb11a55929f7e987d4584d77f9e02192c1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 2 Apr 2016 17:04:23 +0100 Subject: [PATCH 30/51] Removed obsolete PORTAL_LIMIT macro --- src/doomdef.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index c3a0bfa6e..88575ea7c 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -427,10 +427,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; // None of these that are disabled in the normal build are guaranteed to work perfectly // Compile them at your own risk! -/// Max recursive portal renders -/// \note obsoleted by cv_maxportals -//#define PORTAL_LIMIT 8 - /// Kalaron/Eternity Engine slope code (SRB2CB ported) #define ESLOPE From 5f3beb68992828cd4a82fc652a4dc740290d1af7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 2 Apr 2016 20:09:00 +0100 Subject: [PATCH 31/51] Fix M_PI not being defined for Visual Studio --- src/doomdef.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doomdef.h b/src/doomdef.h index 88575ea7c..e6327998a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -101,6 +101,7 @@ #include #include +#define _USE_MATH_DEFINES // fixes M_PI errors in r_plane.c for Visual Studio #include #ifdef GETTEXT From 1db51f5a23117c0750da916fa186dfae732b7358 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Sun, 3 Apr 2016 19:49:27 -0700 Subject: [PATCH 32/51] doomed# 750 shouldn't ever spawn objects --- src/p_mobj.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4e60ad612..be1fd9a02 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8557,6 +8557,9 @@ void P_SpawnMapThing(mapthing_t *mthing) return; } + else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn) + return; + else if (mthing->type == 300 // Ring || mthing->type == 308 || mthing->type == 309 // Team Rings || mthing->type == 1706 // Nights Wing @@ -8590,8 +8593,7 @@ void P_SpawnMapThing(mapthing_t *mthing) if (i == NUMMOBJTYPES) { - if (mthing->type == 3328 // 3D Mode start Thing - || mthing->type == 750) // Chaos mode spawn + if (mthing->type == 3328) // 3D Mode start Thing return; CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); i = MT_UNKNOWN; From 7a369a5650796c007db66126eee1a3826df122f3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 5 Apr 2016 12:39:53 +0100 Subject: [PATCH 33/51] Turns out boss thing types re-setting mthing->z is a left-over from 1.09.4 and older versions Apparently bosses and players used to use options >> 5 instead of 4 for z heights, or so it seems --- src/p_mobj.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index be1fd9a02..42571a5c3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8901,6 +8901,7 @@ void P_SpawnMapThing(mapthing_t *mthing) const size_t mthingi = (size_t)(mthing - mapthings); // Why does P_FindSpecialLineFromTag not work here?!? + // Monster Iestyn: tag lists haven't been initialised yet for the map, that's why for (line = 0; line < numlines; line++) { if (lines[line].special == 9 && lines[line].tag == mthing->angle) @@ -9050,10 +9051,6 @@ ML_NOCLIMB : Direction not controllable { if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss mobj->flags2 |= MF2_BOSSNOTRAP; - - z = ss->sector->floorheight + ((mthing->options >> (ZSHIFT)) << FRACBITS); - - mthing->z = (INT16)(z>>FRACBITS); } if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) // Axis Points From 69a58d836963b0cd1c8325fa3b3162c1418debe9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 5 Apr 2016 15:33:55 +0100 Subject: [PATCH 34/51] Fix lighting parity between resolutions for sprites and FOFs --- src/r_segs.c | 6 +++--- src/r_things.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 252f6face..0e2b9ea5c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -198,7 +198,7 @@ static void R_DrawWallSplats(void) // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++, spryscale += rw_scalestep) { - pindex = spryscale>>LIGHTSCALESHIFT; + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE - 1; dc_colormap = walllights[pindex]; @@ -942,7 +942,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else xwalllights = scalelight[lightnum]; - pindex = spryscale>>LIGHTSCALESHIFT; + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE-1; @@ -1030,7 +1030,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } // calculate lighting - pindex = spryscale>>LIGHTSCALESHIFT; + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE - 1; diff --git a/src/r_things.c b/src/r_things.c index f4e5e07a1..5616c2224 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1013,7 +1013,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW) && (!newsprite->extra_colormap || !newsprite->extra_colormap->fog))) { - lindex = sprite->xscale>>(LIGHTSCALESHIFT); + lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT); if (lindex >= MAXLIGHTSCALE) lindex = MAXLIGHTSCALE-1; @@ -1329,7 +1329,7 @@ static void R_ProjectSprite(mobj_t *thing) else { // diminished light - lindex = xscale>>(LIGHTSCALESHIFT); + lindex = FixedMul(xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT); if (lindex >= MAXLIGHTSCALE) lindex = MAXLIGHTSCALE-1; From e91cfa7110eaedb8b347fa50a95bb1c74dcc303f Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 6 Apr 2016 08:16:13 -0700 Subject: [PATCH 35/51] Fixed frustrating MIDI stuff Until we use something besides Native MIDI to play back MIDI music, MIDI volume changing is disabled since it causes way too much of a damn headache. (It's not even our fault, it's fucking MS.) --- src/s_sound.c | 3 +-- src/sdl/mixer_sound.c | 27 ++++++++++++--------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 49373d94c..0bb8f3e2b 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1310,8 +1310,7 @@ void S_SetDigMusicVolume(INT32 volume) #ifdef DJGPPDOS I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. #endif - if (!nodigimusic) - I_SetDigMusicVolume(volume&31); + I_SetDigMusicVolume(volume&31); } void S_SetMIDIMusicVolume(INT32 volume) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 0f96f4733..9eb5c3154 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -529,14 +529,8 @@ boolean I_StartDigSong(const char *musicname, boolean looping) #endif if (lumpnum == LUMPERROR) - { - lumpnum = W_CheckNumForName(va("D_%s",musicname)); - if (lumpnum == LUMPERROR) - return false; - midimode = true; - } - else - midimode = false; + return false; + midimode = false; data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC); len = W_LumpLength(lumpnum); @@ -686,10 +680,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); return true; } - if (midimode) - Mix_VolumeMusic((UINT32)midi_volume*128/31); - else - Mix_VolumeMusic((UINT32)music_volume*128/31); + Mix_VolumeMusic((UINT32)music_volume*128/31); if (loop_point != 0.0f) Mix_HookMusicFinished(music_loop); @@ -792,10 +783,15 @@ void I_ShutdownMIDIMusic(void) void I_SetMIDIMusicVolume(UINT8 volume) { - midi_volume = volume; + // HACK: Until we stop using native MIDI, + // disable volume changes + (void)volume; + midi_volume = 31; + //midi_volume = volume; + if (!midimode || !music) return; - Mix_VolumeMusic((UINT32)volume*128/31); + Mix_VolumeMusic((UINT32)midi_volume*128/31); } INT32 I_RegisterSong(void *data, size_t len) @@ -820,7 +816,8 @@ boolean I_PlaySong(INT32 handle, boolean looping) CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); return false; } - Mix_VolumeMusic((UINT32)music_volume*128/31); + + Mix_VolumeMusic((UINT32)midi_volume*128/31); return true; } From b1e736242fceab97c0a868fd67154bd77bb67d87 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 6 Apr 2016 22:19:39 +0100 Subject: [PATCH 36/51] fixed all compiling errors relating to ESLOPE being undefined --- src/p_map.c | 4 ++++ src/p_maputl.c | 8 ++++++++ src/p_mobj.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/p_saveg.c | 10 ++++++++++ src/p_spec.c | 2 ++ src/r_main.c | 2 ++ src/r_segs.c | 14 +++++++++++++- 7 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 5cd601272..612f15220 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1146,13 +1146,17 @@ static boolean PIT_CheckLine(line_t *ld) { tmceilingz = opentop; ceilingline = ld; +#ifdef ESLOPE tmceilingslope = opentopslope; +#endif } if (openbottom > tmfloorz) { tmfloorz = openbottom; +#ifdef ESLOPE tmfloorslope = openbottomslope; +#endif } if (highceiling > tmdrpoffceilz) diff --git a/src/p_maputl.c b/src/p_maputl.c index 82d9bbfe4..6bd94362f 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -527,13 +527,17 @@ void P_LineOpening(line_t *linedef) { opentop = frontheight; highceiling = backheight; +#ifdef ESLOPE opentopslope = front->c_slope; +#endif } else { opentop = backheight; highceiling = frontheight; +#ifdef ESLOPE opentopslope = back->c_slope; +#endif } frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); @@ -543,13 +547,17 @@ void P_LineOpening(line_t *linedef) { openbottom = frontheight; lowfloor = backheight; +#ifdef ESLOPE openbottomslope = front->f_slope; +#endif } else { openbottom = backheight; lowfloor = frontheight; +#ifdef ESLOPE openbottomslope = back->f_slope; +#endif } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 2bab28bc6..9a33eb65c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -752,6 +752,7 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) return true; } +#ifdef ESLOPE // P_GetFloorZ (and its ceiling counterpart) // Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y] // If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line @@ -855,10 +856,13 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, P_GetZAt(slope, v2.x, v2.y) ); } +#endif fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { +#ifdef ESLOPE I_Assert(mobj != NULL); +#endif I_Assert(sector != NULL); #ifdef ESLOPE if (sector->f_slope) { @@ -930,13 +934,23 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height +#else + (void)mobj; + (void)boundsec; + (void)x; + (void)y; + (void)line; + (void)lowest; + (void)perfect; #endif return sector->floorheight; } fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { +#ifdef ESLOPE I_Assert(mobj != NULL); +#endif I_Assert(sector != NULL); #ifdef ESLOPE if (sector->c_slope) { @@ -1008,6 +1022,14 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height +#else + (void)mobj; + (void)boundsec; + (void)x; + (void)y; + (void)line; + (void)lowest; + (void)perfect; #endif return sector->ceilingheight; } @@ -1015,7 +1037,9 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed // Now do the same as all above, but for cameras because apparently cameras are special? fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { +#ifdef ESLOPE I_Assert(mobj != NULL); +#endif I_Assert(sector != NULL); #ifdef ESLOPE if (sector->f_slope) { @@ -1087,13 +1111,23 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height +#else + (void)mobj; + (void)boundsec; + (void)x; + (void)y; + (void)line; + (void)lowest; + (void)perfect; #endif return sector->floorheight; } fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { +#ifdef ESLOPE I_Assert(mobj != NULL); +#endif I_Assert(sector != NULL); #ifdef ESLOPE if (sector->c_slope) { @@ -1165,6 +1199,14 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height +#else + (void)mobj; + (void)boundsec; + (void)x; + (void)y; + (void)line; + (void)lowest; + (void)perfect; #endif return sector->ceilingheight; } diff --git a/src/p_saveg.c b/src/p_saveg.c index e0112bb79..c38a1ebbe 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -924,8 +924,12 @@ typedef enum MD2_EXTVAL1 = 1<<5, MD2_EXTVAL2 = 1<<6, MD2_HNEXT = 1<<7, +#ifdef ESLOPE MD2_HPREV = 1<<8, MD2_SLOPE = 1<<9 +#else + MD2_HPREV = 1<<8 +#endif } mobj_diff2_t; typedef enum @@ -1115,8 +1119,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_HNEXT; if (mobj->hprev) diff2 |= MD2_HPREV; +#ifdef ESLOPE if (mobj->standingslope) diff2 |= MD2_SLOPE; +#endif if (diff2 != 0) diff |= MD_MORE; @@ -1232,8 +1238,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->hnext->mobjnum); if (diff2 & MD2_HPREV) WRITEUINT32(save_p, mobj->hprev->mobjnum); +#ifdef ESLOPE if (diff2 & MD2_SLOPE) WRITEUINT16(save_p, mobj->standingslope->id); +#endif WRITEUINT32(save_p, mobj->mobjnum); } @@ -2087,8 +2095,10 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_HPREV) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); +#ifdef ESLOPE if (diff2 & MD2_SLOPE) mobj->standingslope = P_SlopeById(READUINT16(save_p)); +#endif if (diff & MD_REDFLAG) diff --git a/src/p_spec.c b/src/p_spec.c index 76c3484c6..a903aa5a5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4672,8 +4672,10 @@ void P_UpdateSpecials(void) // POINT LIMIT P_CheckPointLimit(); +#ifdef ESLOPE // Dynamic slopeness P_RunDynamicSlopes(); +#endif // ANIMATE TEXTURES for (anim = anims; anim < lastanim; anim++) diff --git a/src/r_main.c b/src/r_main.c index a6b13302e..39958305d 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -517,7 +517,9 @@ static void R_InitTextureMapping(void) focallength = FixedDiv(centerxfrac, FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); +#ifdef ESLOPE focallengthf = FIXED_TO_FLOAT(focallength); +#endif for (i = 0; i < FINEANGLES/2; i++) { diff --git a/src/r_segs.c b/src/r_segs.c index 6efac9028..fd0bde33b 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -288,7 +288,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) line_t *ldef; sector_t *front, *back; INT32 times, repeats; +#ifdef ESLOPE INT32 range; +#endif // Calculate light table. // Use different light tables @@ -335,7 +337,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) colfunc = fuzzcolfunc; } +#ifdef ESLOPE range = max(ds->x2-ds->x1, 1); +#endif rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; @@ -695,7 +699,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t offsetvalue = 0; lightlist_t *light; r_lightlist_t *rlight; +#ifdef ESLOPE INT32 range; +#endif #ifndef ESLOPE fixed_t lheight; #endif @@ -760,7 +766,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else if (pfloor->flags & FF_FOG) colfunc = R_DrawFogColumn_8; +#ifdef ESLOPE range = max(ds->x2-ds->x1, 1); +#endif //SoM: Moved these up here so they are available for my lightlist calculations rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; @@ -1192,7 +1200,9 @@ static void R_RenderSegLoop (void) INT32 mid; fixed_t texturecolumn = 0; +#ifdef ESLOPE fixed_t oldtexturecolumn = -1; +#endif INT32 top; INT32 bottom; INT32 i; @@ -1548,7 +1558,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t hyp; fixed_t sineval; angle_t distangle, offsetangle; - //fixed_t vtop; +#ifndef ESLOPE + fixed_t vtop; +#endif INT32 lightnum; INT32 i, p; lightlist_t *light; From 5aea82ec9173625ec36a8d8f23ad48c6b5d552c8 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 6 Apr 2016 18:01:01 -0700 Subject: [PATCH 37/51] Some drawing code cleanup Fixed mashing buttons during fades causing crashes, messed up behavior, record attack anywhere, all the damn stupid bugs that it caused, basically --- src/d_main.c | 68 ++++++++++++++++------------------------------- src/m_menu.c | 72 +++++++++++++++++++++++++++++++++++--------------- src/st_stuff.c | 7 +++-- src/st_stuff.h | 2 +- 4 files changed, 79 insertions(+), 70 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index b04c55cbf..c9282be7e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -221,10 +221,7 @@ gamestate_t wipegamestate = GS_LEVEL; static void D_Display(void) { - static boolean menuactivestate = false; - static gamestate_t oldgamestate = -1; - boolean redrawsbar = false; - + boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; @@ -245,23 +242,15 @@ static void D_Display(void) if (setsizeneeded) { R_ExecuteSetViewSize(); - oldgamestate = -1; // force background redraw - redrawsbar = true; + forcerefresh = true; // force background redraw } - // save the current screen if about to wipe - if (gamestate != wipegamestate) - { - wipe = true; - F_WipeStartScreen(); - } - else - wipe = false; - // draw buffered stuff to screen // Used only by linux GGI version I_UpdateNoBlit(); + // save the current screen if about to wipe + wipe = (gamestate != wipegamestate); if (wipe) { // set for all later @@ -280,6 +269,7 @@ static void D_Display(void) if (gamestate != GS_LEVEL // fades to black on its own timing, always && wipedefs[wipedefindex] != UINT8_MAX) { + F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); @@ -298,8 +288,6 @@ static void D_Display(void) HU_Erase(); if (automapactive) AM_Drawer(); - if (wipe || menuactivestate || (rendermode != render_soft && rendermode != render_none) || vid.recalc) - redrawsbar = true; break; case GS_INTERMISSION: @@ -357,11 +345,6 @@ static void D_Display(void) // see if the border needs to be initially drawn if (gamestate == GS_LEVEL) { -#if 0 - if (oldgamestate != GS_LEVEL) - R_FillBackScreen(); // draw the pattern into the back screen -#endif - // draw the view directly if (!automapactive && !dedicated && cv_renderview.value) { @@ -417,17 +400,17 @@ static void D_Display(void) lastdraw = false; } - ST_Drawer(redrawsbar); + ST_Drawer(); HU_Drawer(); } // change gamma if needed - if (gamestate != oldgamestate && gamestate != GS_LEVEL) + // (GS_LEVEL handles this already due to level-specific palettes) + if (forcerefresh && gamestate != GS_LEVEL) V_SetPalette(0); - menuactivestate = menuactive; - oldgamestate = wipegamestate = gamestate; + wipegamestate = gamestate; // draw pause pic if (paused && cv_showhud.value && (!menuactive || netgame)) @@ -450,15 +433,22 @@ static void D_Display(void) CON_Drawer(); M_Drawer(); // menu is drawn even on top of everything + // focus lost moved to M_Drawer - // focus lost notification goes on top of everything, even the former everything - if (window_notinfocus) + // + // wipe update + // + if (wipe) { - M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2); - if (gamestate == GS_LEVEL && (P_AutoPause() || paused)) - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused"); - else - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost"); + // note: moved up here because NetUpdate does input changes + // and input during wipe tends to mess things up + wipedefindex += WIPEFINALSHIFT; + + if (rendermode != render_none) + { + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + } } NetUpdate(); // send out any new accumulation @@ -493,18 +483,6 @@ static void D_Display(void) } I_FinishUpdate(); // page flip or blit buffer - return; - } - - // - // wipe update - // - wipedefindex += WIPEFINALSHIFT; - - if (rendermode != render_none) - { - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); } } diff --git a/src/m_menu.c b/src/m_menu.c index 95752c7aa..3aad54282 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2059,6 +2059,10 @@ static void M_PrevOpt(void) } while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE); } +// lock out further input in a tic when important buttons are pressed +// (in other words -- stop bullshit happening by mashing buttons in fades) +static boolean noFurtherInput = false; + // // M_Responder // @@ -2081,6 +2085,12 @@ boolean M_Responder(event_t *ev) shiftdown = false; return false; } + if (noFurtherInput) + { + // Ignore input after enter/escape/other buttons + // (but still allow shift keyup so caps doesn't get stuck) + return false; + } else if (ev->type == ev_keydown) { ch = ev->data1; @@ -2182,6 +2192,7 @@ boolean M_Responder(event_t *ev) // F-Keys if (!menuactive) { + noFurtherInput = true; switch (ch) { case KEY_F1: // Help key @@ -2252,6 +2263,7 @@ boolean M_Responder(event_t *ev) M_StartControlPanel(); return true; } + noFurtherInput = false; // turns out we didn't care return false; } @@ -2275,6 +2287,7 @@ boolean M_Responder(event_t *ev) if (routine) routine(ch); M_StopMessage(0); + noFurtherInput = true; return true; } return true; @@ -2354,6 +2367,7 @@ boolean M_Responder(event_t *ev) return true; case KEY_ENTER: + noFurtherInput = true; currentMenu->lastOn = itemOn; if (routine) { @@ -2387,6 +2401,7 @@ boolean M_Responder(event_t *ev) return true; case KEY_ESCAPE: + noFurtherInput = true; currentMenu->lastOn = itemOn; if (currentMenu->prevMenu) { @@ -2443,35 +2458,45 @@ void M_Drawer(void) if (currentMenu == &MessageDef) menuactive = true; - if (!menuactive) - return; - - // now that's more readable with a faded background (yeah like Quake...) - if (!WipeInAction) - V_DrawFadeScreen(); - - if (currentMenu->drawroutine) - currentMenu->drawroutine(); // call current menu Draw routine - - // Draw version down in corner - // ... but only in the MAIN MENU. I'm a picky bastard. - if (currentMenu == &MainDef) + if (menuactive) { - if (customversionstring[0] != '\0') - { - V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:"); - V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring); - } - else + // now that's more readable with a faded background (yeah like Quake...) + if (!WipeInAction) + V_DrawFadeScreen(); + + if (currentMenu->drawroutine) + currentMenu->drawroutine(); // call current menu Draw routine + + // Draw version down in corner + // ... but only in the MAIN MENU. I'm a picky bastard. + if (currentMenu == &MainDef) { + if (customversionstring[0] != '\0') + { + V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:"); + V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring); + } + else + { #ifdef DEVELOP // Development -- show revision / branch info - V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch); - V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision); + V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch); + V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision); #else // Regular build - V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING)); + V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING)); #endif + } } } + + // focus lost notification goes on top of everything, even the former everything + if (window_notinfocus) + { + M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2); + if (gamestate == GS_LEVEL && (P_AutoPause() || paused)) + V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused"); + else + V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost"); + } } // @@ -2656,6 +2681,9 @@ void M_SetupNextMenu(menu_t *menudef) // void M_Ticker(void) { + // reset input trigger + noFurtherInput = false; + if (dedicated) return; diff --git a/src/st_stuff.c b/src/st_stuff.c index 585db0c87..9a4df8a07 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1889,7 +1889,7 @@ static void ST_overlayDrawer(void) ST_drawDebugInfo(); } -void ST_Drawer(boolean refresh) +void ST_Drawer(void) { #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) @@ -1906,8 +1906,11 @@ void ST_Drawer(boolean refresh) } #endif + // Doom's status bar only updated if necessary. + // However, ours updates every frame regardless, so the "refresh" param was removed + //(void)refresh; + // force a set of the palette by using doPaletteStuff() - (void)refresh; //? if (vid.recalc) st_palette = -1; diff --git a/src/st_stuff.h b/src/st_stuff.h index 9873efbe7..44994a6d3 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -27,7 +27,7 @@ void ST_Ticker(void); // Called by main loop. -void ST_Drawer(boolean refresh); +void ST_Drawer(void); // Called when the console player is spawned on each level. void ST_Start(void); From 3117a6a16e145ef044f6bd545f6fdc7fed41e684 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 6 Apr 2016 18:28:43 -0700 Subject: [PATCH 38/51] Splitscreen fixes initialize flipcam2 player 2 gets game over music now. restore the other player's music when the dead player is done sulking about their game over --- src/d_clisrv.c | 6 +++--- src/p_inter.c | 2 +- src/p_user.c | 21 +++++++++++++++++++-- src/r_main.c | 1 + 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c0179ca1b..d20c0e5ea 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2935,9 +2935,9 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (botingame) players[newplayernum].bot = 1; // Same goes for player 2 when relevant - players[newplayernum].pflags &= ~(/*PF_FLIPCAM|*/PF_ANALOGMODE); - //if (cv_flipcam2.value) - //players[newplayernum].pflags |= PF_FLIPCAM; + players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); + if (cv_flipcam2.value) + players[newplayernum].pflags |= PF_FLIPCAM; if (cv_analog2.value) players[newplayernum].pflags |= PF_ANALOGMODE; } diff --git a/src/p_inter.c b/src/p_inter.c index b8101f12b..8fb517d5c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2068,7 +2068,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) if (target->player->lives <= 0) // Tails 03-14-2000 { - if (P_IsLocalPlayer(target->player) && target->player == &players[consoleplayer]) + if (P_IsLocalPlayer(target->player)/* && target->player == &players[consoleplayer] */) { S_StopMusic(); // Stop the Music! Tails 03-14-2000 S_ChangeMusicInternal("gmover", false); // Yousa dead now, Okieday? Tails 03-14-2000 diff --git a/src/p_user.c b/src/p_user.c index 45dd47639..6942f2fcd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7716,8 +7716,25 @@ static void P_DeathThink(player_t *player) } // Return to level music - if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); + if (player->lives <= 0) + { + if (netgame) + { + if (player->deadtimer == gameovertics && P_IsLocalPlayer(player)) + S_ChangeMusic(mapmusname, mapmusflags, true); + } + else if (multiplayer) // local multiplayer only + { + if (player->deadtimer != gameovertics) + ; + // Restore the other player's music once we're dead for long enough + // -- that is, as long as they aren't dead too + else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0) + P_RestoreMusic(&players[secondarydisplayplayer]); + else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0) + P_RestoreMusic(&players[displayplayer]); + } + } } if (!player->mo) diff --git a/src/r_main.c b/src/r_main.c index a6b13302e..3b71b7f92 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1382,6 +1382,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_allowmlook); CV_RegisterVar(&cv_homremoval); CV_RegisterVar(&cv_flipcam); + CV_RegisterVar(&cv_flipcam2); // Enough for dedicated server if (dedicated) From 0dd92e93966cec1577953e560507753b140a5aa6 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 6 Apr 2016 18:33:38 -0700 Subject: [PATCH 39/51] V_DrawFill in OGL now consistent with software --- src/hardware/hw_draw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index e6a26e605..60183b58e 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -657,6 +657,9 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) FOutVector v[4]; FSurfaceInfo Surf; + if (w < 0 || h < 0) + return; // consistency w/ software + // 3--2 // | /| // |/ | From 3b4b7a05fdc6ff5c74c6a56c58599f1213fa6c31 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 6 Apr 2016 19:55:58 -0700 Subject: [PATCH 40/51] Better CTF in splitscreen, no death message for spectators --- src/p_inter.c | 66 +++++++++++++++++++++++++++++++++++++++++---------- src/p_mobj.c | 10 ++++---- src/p_spec.c | 4 ++-- src/p_user.c | 4 ++-- 4 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 8fb517d5c..c08f1f267 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -27,6 +27,10 @@ #include "m_misc.h" #include "v_video.h" // video flags for CEchos +// CTF player names +#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" +#define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : "" + void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period) { BasicFF_t Basicfeed; @@ -574,11 +578,23 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { UINT8 flagteam = (special->type == MT_REDFLAG) ? 1 : 2; const char *flagtext; + char flagcolor; + char plname[MAXPLAYERNAME+4]; if (special->type == MT_REDFLAG) - flagtext = M_GetText("red"); + { + flagtext = M_GetText("Red flag"); + flagcolor = '\x85'; + } else - flagtext = M_GetText("blue"); + { + flagtext = M_GetText("Blue flag"); + flagcolor = '\x84'; + } + snprintf(plname, sizeof(plname), "%s%s%s", + CTFTEAMCODE(player), + player_names[player - players], + CTFTEAMENDCODE(player)); if (player->ctfteam == flagteam) // Player is on the same team as the flag { @@ -592,10 +608,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_PlayerTouchingSectorSpecial(player, 4, 2 + flagteam)) { - CONS_Printf(M_GetText("%s returned the %s flag to base.\n"), player_names[player-players], flagtext); + CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80); - if (players[consoleplayer].ctfteam == player->ctfteam) - S_StartSound(NULL, sfx_hoop1); + // The fuse code plays this sound effect + //if (players[consoleplayer].ctfteam == player->ctfteam) + // S_StartSound(NULL, sfx_hoop1); } } } @@ -608,7 +625,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; player->gotflag |= flagflag; - CONS_Printf(M_GetText("%s picked up the %s flag!\n"), player_names[player-players], flagtext); + CONS_Printf(M_GetText("%s picked up the %c%s%c!\n"), plname, flagcolor, flagtext, 0x80); (*flagmobj) = NULL; // code for dealing with abilities is handled elsewhere now break; @@ -1447,9 +1464,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_KillMobj(special, NULL, toucher); } -#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" -#define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : "" - /** Prints death messages relating to a dying or hit player. * * \param player Affected player. @@ -1472,6 +1486,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour if (!player) return; // Impossible! + if (player->spectator) + return; // No messages for dying (crushed) spectators. + if (!netgame) return; // Presumably it's obvious what's happening in splitscreen. @@ -3618,10 +3635,33 @@ void P_PlayerFlagBurst(player_t *player, boolean toss) flag->fuse = cv_flagtime.value * TICRATE; P_SetTarget(&flag->target, player->mo); - if (toss) - CONS_Printf(M_GetText("%s tossed the %s flag.\n"), player_names[player-players], (type == MT_REDFLAG ? "red" : "blue")); - else - CONS_Printf(M_GetText("%s dropped the %s flag.\n"), player_names[player-players], (type == MT_REDFLAG ? "red" : "blue")); + // Flag text + { + char plname[MAXPLAYERNAME+4]; + char *flagtext; + char flagcolor; + + snprintf(plname, sizeof(plname), "%s%s%s", + CTFTEAMCODE(player), + player_names[player - players], + CTFTEAMENDCODE(player)); + + if (type == MT_REDFLAG) + { + flagtext = M_GetText("Red flag"); + flagcolor = '\x85'; + } + else + { + flagtext = M_GetText("Blue flag"); + flagcolor = '\x84'; + } + + if (toss) + CONS_Printf(M_GetText("%s tossed the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80); + else + CONS_Printf(M_GetText("%s dropped the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80); + } player->gotflag = 0; diff --git a/src/p_mobj.c b/src/p_mobj.c index 42571a5c3..ce67f1a5a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7149,9 +7149,10 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->type == MT_REDFLAG) { if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The red flag has returned to base.\n")); + CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); - if (players[consoleplayer].ctfteam == 1) + // Assumedly in splitscreen players will be on opposing teams + if (players[consoleplayer].ctfteam == 1 || splitscreen) S_StartSound(NULL, sfx_hoop1); redflag = flagmo; @@ -7159,9 +7160,10 @@ void P_MobjThinker(mobj_t *mobj) else // MT_BLUEFLAG { if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The blue flag has returned to base.\n")); + CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); - if (players[consoleplayer].ctfteam == 2) + // Assumedly in splitscreen players will be on opposing teams + if (players[consoleplayer].ctfteam == 2 || splitscreen) S_StartSound(NULL, sfx_hoop1); blueflag = flagmo; diff --git a/src/p_spec.c b/src/p_spec.c index 76c3484c6..37a059461 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3781,7 +3781,7 @@ DoneSection2: HU_SetCEchoDuration(5); HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players])); - if (players[consoleplayer].ctfteam == 1) + if (splitscreen || players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_flgcap); else if (players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_lose); @@ -3814,7 +3814,7 @@ DoneSection2: HU_SetCEchoDuration(5); HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players])); - if (players[consoleplayer].ctfteam == 2) + if (splitscreen || players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_flgcap); else if (players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_lose); diff --git a/src/p_user.c b/src/p_user.c index 6942f2fcd..72d99d6d1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8456,9 +8456,9 @@ static boolean P_SpectatorJoinGame(player_t *player) displayplayer = consoleplayer; if (changeto == 1) - CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x85', M_GetText("Red Team"), '\x80'); + CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x85', M_GetText("Red team"), '\x80'); else if (changeto == 2) - CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x84', M_GetText("Blue Team"), '\x80'); + CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x84', M_GetText("Blue team"), '\x80'); return true; // no more player->mo, cannot continue. } From b9eed02123ad85bfa0757b94301d89ec21475452 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 7 Apr 2016 16:34:36 -0400 Subject: [PATCH 41/51] whitespace clean --- src/g_game.c | 4 ++-- src/lua_hook.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 9578cbf8f..1f6834ac5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2331,8 +2331,8 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) } } P_MovePlayerToSpawn(playernum, spawnpoint); - -#ifdef HAVE_BLUA + +#ifdef HAVE_BLUA LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :) #endif diff --git a/src/lua_hook.h b/src/lua_hook.h index 4eb083780..df0ea43fa 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -76,6 +76,6 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_B boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages -#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer +#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer #endif From 7830a9e27baa14c6ad9318669ff6129446071d51 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 10 Apr 2016 20:27:55 +0100 Subject: [PATCH 42/51] Splitscreen fix: half of GFZ1's invinc monitor should no longer appear above the bridge for player 2 I don't know if there's any other vid.height/viewheight confusion like this around, but that was the cause apparently --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 5616c2224..2ec2f6ead 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -964,7 +964,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); if (cutfrac < 0) continue; - if (cutfrac > vid.height) + if (cutfrac > viewheight) return; // Found a split! Make a new sprite, copy the old sprite to it, and From f96b830f36916d71ec78e24f91d202401b586933 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 16 Apr 2016 18:06:26 +0100 Subject: [PATCH 43/51] Write/read FOF flags as 32-bit not 16-bit, whoops --- src/p_saveg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index e0112bb79..952e567d7 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -613,7 +613,7 @@ static void P_NetArchiveWorld(void) WRITEUINT16(put, j); // save ffloor "number" WRITEUINT8(put, fflr_diff); if (fflr_diff & 1) - WRITEUINT16(put, rover->flags); + WRITEUINT32(put, rover->flags); if (fflr_diff & 2) WRITEINT16(put, rover->alpha); } @@ -815,7 +815,7 @@ static void P_NetUnArchiveWorld(void) fflr_diff = READUINT8(get); if (fflr_diff & 1) - rover->flags = READUINT16(get); + rover->flags = READUINT32(get); if (fflr_diff & 2) rover->alpha = READINT16(get); From be7b866e4ff102d65ed8c33f5fa907a144acd032 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 16 Apr 2016 18:40:14 +0100 Subject: [PATCH 44/51] resynch_pak changes * add skidtime, which we forgot before 2.1 release apparently * change tics from INT16 to INT32 * change eflags from UINT8 to UINT16 * change actionspd/mindash/maxdash from INT32 to fixed_t --- src/d_clisrv.c | 18 ++++++++++-------- src/d_clisrv.h | 11 ++++++----- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d20c0e5ea..7852a0a22 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -517,9 +517,9 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->thokitem = (UINT32)LONG(players[i].thokitem); //mobjtype_t rsp->spinitem = (UINT32)LONG(players[i].spinitem); //mobjtype_t rsp->revitem = (UINT32)LONG(players[i].revitem); //mobjtype_t - rsp->actionspd = LONG(players[i].actionspd); - rsp->mindash = LONG(players[i].mindash); - rsp->maxdash = LONG(players[i].maxdash); + rsp->actionspd = (fixed_t)LONG(players[i].actionspd); + rsp->mindash = (fixed_t)LONG(players[i].mindash); + rsp->maxdash = (fixed_t)LONG(players[i].maxdash); rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor); rsp->speed = (fixed_t)LONG(players[i].speed); @@ -531,6 +531,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->deadtimer = players[i].deadtimer; rsp->exiting = (tic_t)LONG(players[i].exiting); rsp->homing = players[i].homing; + rsp->skidtime = (tic_t)LONG(players[i].skidtime); rsp->cmomx = (fixed_t)LONG(players[i].cmomx); rsp->cmomy = (fixed_t)LONG(players[i].cmomy); rsp->rmomx = (fixed_t)LONG(players[i].rmomx); @@ -590,7 +591,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->tics = LONG(players[i].mo->tics); rsp->statenum = (statenum_t)LONG(players[i].mo->state-states); // :( - rsp->eflags = (UINT32)LONG(players[i].mo->eflags); + rsp->eflags = (UINT16)SHORT(players[i].mo->eflags); rsp->flags = LONG(players[i].mo->flags); rsp->flags2 = LONG(players[i].mo->flags2); @@ -642,9 +643,9 @@ static void resynch_read_player(resynch_pak *rsp) players[i].thokitem = (UINT32)LONG(rsp->thokitem); //mobjtype_t players[i].spinitem = (UINT32)LONG(rsp->spinitem); //mobjtype_t players[i].revitem = (UINT32)LONG(rsp->revitem); //mobjtype_t - players[i].actionspd = LONG(rsp->actionspd); - players[i].mindash = LONG(rsp->mindash); - players[i].maxdash = LONG(rsp->maxdash); + players[i].actionspd = (fixed_t)LONG(rsp->actionspd); + players[i].mindash = (fixed_t)LONG(rsp->mindash); + players[i].maxdash = (fixed_t)LONG(rsp->maxdash); players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor); players[i].speed = (fixed_t)LONG(rsp->speed); @@ -656,6 +657,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].deadtimer = rsp->deadtimer; players[i].exiting = (tic_t)LONG(rsp->exiting); players[i].homing = rsp->homing; + players[i].skidtime = (tic_t)LONG(rsp->skidtime); players[i].cmomx = (fixed_t)LONG(rsp->cmomx); players[i].cmomy = (fixed_t)LONG(rsp->cmomy); players[i].rmomx = (fixed_t)LONG(rsp->rmomx); @@ -713,7 +715,7 @@ static void resynch_read_player(resynch_pak *rsp) //At this point, the player should have a body, whether they were respawned or not. P_UnsetThingPosition(players[i].mo); players[i].mo->angle = (angle_t)LONG(rsp->angle); - players[i].mo->eflags = (UINT32)LONG(rsp->eflags); + players[i].mo->eflags = (UINT16)SHORT(rsp->eflags); players[i].mo->flags = LONG(rsp->flags); players[i].mo->flags2 = LONG(rsp->flags2); players[i].mo->friction = LONG(rsp->friction); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 6bc06f13a..246447ed6 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -177,9 +177,9 @@ typedef struct UINT32 thokitem; //mobjtype_t UINT32 spinitem; //mobjtype_t UINT32 revitem; //mobjtype_t - INT32 actionspd; - INT32 mindash; - INT32 maxdash; + fixed_t actionspd; + fixed_t mindash; + fixed_t maxdash; fixed_t jumpfactor; fixed_t speed; @@ -191,6 +191,7 @@ typedef struct INT32 deadtimer; tic_t exiting; UINT8 homing; + tic_t skidtime; fixed_t cmomx; fixed_t cmomy; fixed_t rmomx; @@ -241,11 +242,11 @@ typedef struct fixed_t friction; fixed_t movefactor; - INT16 tics; + INT32 tics; statenum_t statenum; UINT32 flags; UINT32 flags2; - UINT8 eflags; + UINT16 eflags; fixed_t radius; fixed_t height; From 18d5d64a4d7242a4a532b276f26b773b8ca7d905 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Mon, 18 Apr 2016 14:50:15 -0700 Subject: [PATCH 45/51] error conditions for Lua fixed point math --- src/lua_mathlib.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index fd00180d5..00379b888 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -100,7 +100,11 @@ static int lib_fixedint(lua_State *L) static int lib_fixeddiv(lua_State *L) { - lua_pushfixed(L, FixedDiv(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); + fixed_t i = luaL_checkfixed(L, 1); + fixed_t j = luaL_checkfixed(L, 2); + if (j == 0) + return luaL_error(L, "divide by zero"); + lua_pushfixed(L, FixedDiv(i, j)); return 1; } @@ -112,7 +116,10 @@ static int lib_fixedrem(lua_State *L) static int lib_fixedsqrt(lua_State *L) { - lua_pushfixed(L, FixedSqrt(luaL_checkfixed(L, 1))); + fixed_t i = luaL_checkfixed(L, 1); + if (i < 0) + return luaL_error(L, "can't take the square root of a negative number"); + lua_pushfixed(L, FixedSqrt(i)); return 1; } From a26989c903f3c9dca8754a20cbd3d970a9c493d2 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Mon, 18 Apr 2016 21:59:33 -0700 Subject: [PATCH 46/51] brevity is a virtue or something like that --- src/lua_mathlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 00379b888..a55e3a0e4 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -118,7 +118,7 @@ static int lib_fixedsqrt(lua_State *L) { fixed_t i = luaL_checkfixed(L, 1); if (i < 0) - return luaL_error(L, "can't take the square root of a negative number"); + return luaL_error(L, "square root domain error"); lua_pushfixed(L, FixedSqrt(i)); return 1; } From 0aba2f607ba0cdfc723d41ea2bb4dc24b1ccb6cc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 20 Apr 2016 18:04:51 +0100 Subject: [PATCH 47/51] Fix FOFs with FF_CUTSOLIDS but not FF_SOLID causing software renderer problems and even crashes Always wondered why a flag meant for FOF physics was used in the rendering code, lol --- src/r_segs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 3171bced6..d656108f6 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1352,7 +1352,7 @@ static void R_RenderSegLoop (void) for (i = 0; i < dc_numlights; i++) { dc_lightlist[i].height += dc_lightlist[i].heightstep; - if (dc_lightlist[i].flags & FF_SOLID) + if (dc_lightlist[i].flags & FF_CUTSOLIDS) dc_lightlist[i].botheight += dc_lightlist[i].botheightstep; } } @@ -2001,7 +2001,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); rlight->flags = light->flags; - if (light->caster && light->caster->flags & FF_SOLID) + if (light->caster && light->caster->flags & FF_CUTSOLIDS) { rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); From 69b43aee2dd27e1d1f89f6ac593fae2fa21a2633 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 20 Apr 2016 20:26:41 +0100 Subject: [PATCH 48/51] Fix how FF_CUTEXTRA FOFs carry over cutting ability to FOFs below them in the same sector, even if they shouldn't do that --- src/r_segs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/r_segs.c b/src/r_segs.c index d656108f6..ff8de7cac 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -927,6 +927,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } } + solid = 0; // don't carry over solid-cutting flag from the previous light + // Check if the current light can cut the current 3D floor. if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) solid = 1; From d53801c85c23991a8c672175d033bae240829ce1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 21 Apr 2016 18:50:30 +0100 Subject: [PATCH 49/51] Disable the corona-related consvars unless ALAM_LIGHTING macro is enabled --- src/hardware/hw_main.h | 2 ++ src/r_main.c | 2 ++ src/v_video.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index af7d821b1..b0a14d3b5 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -74,10 +74,12 @@ FUNCMATH UINT8 LightLevelToLum(INT32 l); extern CV_PossibleValue_t granisotropicmode_cons_t[]; +#ifdef ALAM_LIGHTING extern consvar_t cv_grdynamiclighting; extern consvar_t cv_grstaticlighting; extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronasize; +#endif extern consvar_t cv_grfov; extern consvar_t cv_grmd2; extern consvar_t cv_grfog; diff --git a/src/r_main.c b/src/r_main.c index 1e40a85b6..d5de22026 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1461,10 +1461,12 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_voodoocompatibility); CV_RegisterVar(&cv_grfogcolor); CV_RegisterVar(&cv_grsoftwarefog); +#ifdef ALAM_LIGHTING CV_RegisterVar(&cv_grstaticlighting); CV_RegisterVar(&cv_grdynamiclighting); CV_RegisterVar(&cv_grcoronas); CV_RegisterVar(&cv_grcoronasize); +#endif CV_RegisterVar(&cv_grmd2); #endif diff --git a/src/v_video.c b/src/v_video.c index b9bdb271f..96d7fd8d0 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -71,10 +71,12 @@ consvar_t cv_grgammagreen = {"gr_gammagreen", "127", CV_SAVE|CV_CALL, grgamma_co CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grgammablue = {"gr_gammablue", "127", CV_SAVE|CV_CALL, grgamma_cons_t, CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; +#ifdef ALAM_LIGHTING consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; +#endif static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}}; // console variables in development From b8cc36dfd19913b731304b95a67d993e2624471e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 22 Apr 2016 22:28:00 +0100 Subject: [PATCH 50/51] P_LookForEnemies should not change the player's angle until the target has been decided This fixes a quirk with Shadow with chaos control sometimes throwing the player in the wrong direction --- src/p_user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 72d99d6d1..65ba0bc6f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7512,8 +7512,6 @@ boolean P_LookForEnemies(player_t *player) if (an > ANGLE_90 && an < ANGLE_270) continue; // behind back - player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, mo->x, mo->y); - if (!P_CheckSight(player->mo, mo)) continue; // out of sight @@ -7524,6 +7522,7 @@ boolean P_LookForEnemies(player_t *player) { // Found a target monster P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, closestmo)); + player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, closestmo->x, closestmo->y); return true; } From 0a887948eb456540a69a4de6cefdc5bae398311a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 25 Apr 2016 18:48:14 +0100 Subject: [PATCH 51/51] Ensure pixhigh/pixlow is always set whenever the game decides a top/bottom texture should be drawn This fixes the rendering glitches encountered around slopes in Glacier Gear, yes. :) --- src/r_segs.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 574421fb0..3f11bb364 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2696,11 +2696,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldlowslope >>= 4; #endif - if (worldhigh < worldtop -#ifdef ESLOPE - || worldhighslope < worldtopslope -#endif - ) + if (toptexture) { pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); pixhighstep = -FixedMul (rw_scalestep,worldhigh); @@ -2713,11 +2709,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif } - if (worldlow > worldbottom -#ifdef ESLOPE - || worldlowslope > worldbottomslope -#endif - ) + if (bottomtexture) { pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlowstep = -FixedMul (rw_scalestep,worldlow);