From cfb40d42132b72bcf06f776b5c4e0c9cb6c76a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 13 Apr 2023 19:28:54 +0200 Subject: [PATCH 01/85] Fix crash in R_PointToDist2 when passing -2147483648 --- src/m_fixed.h | 3 ++- src/r_main.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/m_fixed.h b/src/m_fixed.h index 4a5b7ce2a..b9586d653 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -34,6 +34,7 @@ */ typedef INT32 fixed_t; +typedef UINT32 ufixed_t; /*! \brief convert fixed_t into floating number @@ -198,7 +199,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedInt(fixed_t a) */ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv(fixed_t a, fixed_t b) { - if ((abs(a) >> (FRACBITS-2)) >= abs(b)) + if (((ufixed_t)abs(a) >> (FRACBITS-2)) >= (ufixed_t)abs(b)) return (a^b) < 0 ? INT32_MIN : INT32_MAX; return FixedDiv2(a, b); diff --git a/src/r_main.c b/src/r_main.c index ebf7a28bf..5265fe15d 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -364,7 +364,7 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) { angle_t angle; - fixed_t dx, dy, dist; + ufixed_t dx, dy, dist; dx = abs(px1 - px2); dy = abs(py1 - py2); From 4967c296ab9c4056d617b401bfd37889967a0155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 30 Apr 2023 12:43:31 +0200 Subject: [PATCH 02/85] Fix segfaults when P_RemoveMobj is called from MobjSpawn hook --- src/b_bot.c | 3 + src/g_demo.c | 143 ++++---- src/p_enemy.c | 914 ++++++++++++++++++++++++++++++------------------ src/p_floor.c | 3 + src/p_inter.c | 261 ++++++++------ src/p_local.h | 2 +- src/p_map.c | 2 + src/p_mobj.c | 851 +++++++++++++++++++++++++++++--------------- src/p_polyobj.c | 2 + src/p_user.c | 439 ++++++++++++++--------- 10 files changed, 1670 insertions(+), 950 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index d1465f891..aa9ccd33e 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -613,6 +613,9 @@ void B_HandleFlightIndicator(player_t *player) // otherwise, spawn it P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY)); + if (P_MobjWasRemoved(tails->hnext)) + return; // we can't spawn one, so it can't exist + P_SetTarget(&tails->hnext->target, tails); P_SetTarget(&tails->hnext->hprev, tails); P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR); diff --git a/src/g_demo.c b/src/g_demo.c index 0403da16d..d1d1a4a11 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -795,32 +795,40 @@ void G_GhostTicker(void) if (type == MT_GHOST) { mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us - mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); - mobj->sprite = states[mobjinfo[type].spawnstate].sprite; - mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<color = g->mo->color; - mobj->skin = g->mo->skin; - P_SetScale(mobj, (mobj->destscale = g->mo->scale)); - - if (type == MT_THOK) // spintrail-specific modification for MT_THOK + if (!P_MobjWasRemoved(mobj)) { - mobj->frame = FF_TRANS80; - mobj->fuse = mobj->tics; + mobj->sprite = states[mobjinfo[type].spawnstate].sprite; + mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<color = g->mo->color; + mobj->skin = g->mo->skin; + P_SetScale(mobj, (mobj->destscale = g->mo->scale)); + + if (type == MT_THOK) // spintrail-specific modification for MT_THOK + { + mobj->frame = FF_TRANS80; + mobj->fuse = mobj->tics; + } + mobj->tics = -1; // nope. } - mobj->tics = -1; // nope. } - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_UnsetThingPosition(mobj); - mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... - P_SetThingPosition(mobj); - if (!mobj->fuse) - mobj->fuse = 8; - P_SetTarget(&mobj->target, g->mo); + + if (!P_MobjWasRemoved(mobj)) + { + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_UnsetThingPosition(mobj); + mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... + P_SetThingPosition(mobj); + if (!mobj->fuse) + mobj->fuse = 8; + P_SetTarget(&mobj->target, g->mo); + } } } if (xziptic & EZT_HIT) @@ -844,6 +852,8 @@ void G_GhostTicker(void) || health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad. continue; poof = P_SpawnMobj(x, y, z, MT_GHOST); + if (P_MobjWasRemoved(poof)) + continue; poof->angle = angle; poof->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... poof->health = 0; @@ -889,19 +899,22 @@ void G_GhostTicker(void) if (follow) P_RemoveMobj(follow); P_SetTarget(&follow, P_SpawnMobjFromMobj(g->mo, 0, 0, 0, MT_GHOST)); - P_SetTarget(&follow->tracer, g->mo); - follow->tics = -1; - temp = READINT16(g->p)<height = FixedMul(follow->scale, temp); + if (!P_MobjWasRemoved(follow)) + { + P_SetTarget(&follow->tracer, g->mo); + follow->tics = -1; + temp = READINT16(g->p)<height = FixedMul(follow->scale, temp); - if (followtic & FZT_LINKDRAW) - follow->flags2 |= MF2_LINKDRAW; + if (followtic & FZT_LINKDRAW) + follow->flags2 |= MF2_LINKDRAW; - if (followtic & FZT_COLORIZED) - follow->colorized = true; + if (followtic & FZT_COLORIZED) + follow->colorized = true; - if (followtic & FZT_SKIN) - follow->skin = &skins[READUINT8(g->p)]; + if (followtic & FZT_SKIN) + follow->skin = &skins[READUINT8(g->p)]; + } } if (follow) { @@ -1094,28 +1107,35 @@ void G_ReadMetalTic(mobj_t *metal) else { mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK); - mobj->sprite = states[mobjinfo[type].spawnstate].sprite; - mobj->frame = states[mobjinfo[type].spawnstate].frame; - mobj->angle = metal->angle; - mobj->color = metal->color; - mobj->skin = metal->skin; - P_SetScale(mobj, (mobj->destscale = metal->scale)); - - if (type == MT_THOK) // spintrail-specific modification for MT_THOK + if (!P_MobjWasRemoved(mobj)) { - mobj->frame = FF_TRANS70; - mobj->fuse = mobj->tics; + mobj->sprite = states[mobjinfo[type].spawnstate].sprite; + mobj->frame = states[mobjinfo[type].spawnstate].frame; + mobj->angle = metal->angle; + mobj->color = metal->color; + mobj->skin = metal->skin; + P_SetScale(mobj, (mobj->destscale = metal->scale)); + + if (type == MT_THOK) // spintrail-specific modification for MT_THOK + { + mobj->frame = FF_TRANS70; + mobj->fuse = mobj->tics; + } + mobj->tics = -1; // nope. } - mobj->tics = -1; // nope. } - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_UnsetThingPosition(mobj); - mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... - P_SetThingPosition(mobj); - if (!mobj->fuse) - mobj->fuse = 8; - P_SetTarget(&mobj->target, metal); + + if (!P_MobjWasRemoved(mobj)) + { + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_UnsetThingPosition(mobj); + mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... + P_SetThingPosition(mobj); + if (!mobj->fuse) + mobj->fuse = 8; + P_SetTarget(&mobj->target, metal); + } } } if (xziptic & EZT_SPRITE) @@ -1137,19 +1157,22 @@ void G_ReadMetalTic(mobj_t *metal) if (follow) P_RemoveMobj(follow); P_SetTarget(&follow, P_SpawnMobjFromMobj(metal, 0, 0, 0, MT_GHOST)); - P_SetTarget(&follow->tracer, metal); - follow->tics = -1; - temp = READINT16(metal_p)<height = FixedMul(follow->scale, temp); + if (!P_MobjWasRemoved(follow)) + { + P_SetTarget(&follow->tracer, metal); + follow->tics = -1; + temp = READINT16(metal_p)<height = FixedMul(follow->scale, temp); - if (followtic & FZT_LINKDRAW) - follow->flags2 |= MF2_LINKDRAW; + if (followtic & FZT_LINKDRAW) + follow->flags2 |= MF2_LINKDRAW; - if (followtic & FZT_COLORIZED) - follow->colorized = true; + if (followtic & FZT_COLORIZED) + follow->colorized = true; - if (followtic & FZT_SKIN) - follow->skin = &skins[READUINT8(metal_p)]; + if (followtic & FZT_SKIN) + follow->skin = &skins[READUINT8(metal_p)]; + } } if (follow) { @@ -2218,7 +2241,9 @@ void G_AddGhost(char *defdemoname) { // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling. fixed_t z,f,c; fixed_t offset = mthing->z << FRACBITS; - gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST); + P_SetTarget(&gh->mo, P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST)); + if (P_MobjWasRemoved(gh->mo)) + return; gh->mo->angle = FixedAngle(mthing->angle << FRACBITS); f = gh->mo->floorz; c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height; diff --git a/src/p_enemy.c b/src/p_enemy.c index 63d430eb6..6cc68e744 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1200,7 +1200,8 @@ static void P_SharpDust(mobj_t *actor, mobjtype_t type, angle_t ang) -P_ReturnThrustX(actor, ang, 16<angle, actor->radius), actor->height/3, MT_PARTICLE); + if (P_MobjWasRemoved(flume)) + return; + flume->destscale = actor->scale*3; P_SetScale(flume, flume->destscale); P_SetTarget(&flume->target, actor); @@ -1328,12 +1332,15 @@ void A_FaceStabHurl(mobj_t *actor) { if (!hwork->hnext) P_SetTarget(&hwork->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_FACESTABBERSPEAR)); - hwork = hwork->hnext; - hwork->angle = actor->angle + ANGLE_90; - hwork->destscale = FixedSqrt(step*basesize); - P_SetScale(hwork, hwork->destscale); - hwork->fuse = 2; - P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<hnext)) + { + hwork = hwork->hnext; + hwork->angle = actor->angle + ANGLE_90; + hwork->destscale = FixedSqrt(step*basesize); + P_SetScale(hwork, hwork->destscale); + hwork->fuse = 2; + P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<info->raisestate); + if (P_MobjWasRemoved(newchain)) + continue; P_SetTarget(&prevchain->target, newchain); prevchain = newchain; } @@ -2324,10 +2335,13 @@ static void P_VultureHoverParticle(mobj_t *actor) fixed_t pz = P_FloorzAtPos(px, py, actor->z, actor->height); dust = P_SpawnMobj(px, py, pz, MT_ARIDDUST); - P_SetMobjState(dust, (statenum_t)(dust->state - states + P_RandomRange(0, 2))); - P_Thrust(dust, angle, FixedDiv(12*FRACUNIT, max(FRACUNIT, fdist/2))); - dust->momx += actor->momx; - dust->momy += actor->momy; + if (!P_MobjWasRemoved(dust)) + { + P_SetMobjState(dust, (statenum_t)(dust->state - states + P_RandomRange(0, 2))); + P_Thrust(dust, angle, FixedDiv(12*FRACUNIT, max(FRACUNIT, fdist/2))); + dust->momx += actor->momx; + dust->momy += actor->momy; + } angle += ANGLE_45; } } @@ -2422,6 +2436,8 @@ void A_VultureBlast(mobj_t *actor) { angle_t fa = ((i*(angle_t)ANGLE_45) >> ANGLETOFINESHIFT) & FINEMASK; dust = P_SpawnMobj(actor->x + 48*FixedMul(FINECOSINE(fa), -faasin), actor->y + 48*FixedMul(FINECOSINE(fa), faacos), actor->z + actor->height/2 + 48*FINESINE(fa), MT_PARTICLE); + if (P_MobjWasRemoved(dust)) + continue; P_SetScale(dust, 4*FRACUNIT); dust->destscale = FRACUNIT; @@ -2491,10 +2507,13 @@ void A_VultureFly(mobj_t *actor) P_VultureHoverParticle(actor); dust = P_SpawnMobj(actor->x + P_RandomFixed() - FRACUNIT/2, actor->y + P_RandomFixed() - FRACUNIT/2, actor->z + actor->height/2 + P_RandomFixed() - FRACUNIT/2, MT_PARTICLE); - P_SetScale(dust, 2*FRACUNIT); - dust->destscale = FRACUNIT/3; - dust->scalespeed = FRACUNIT/40; - dust->fuse = TICRATE*2; + if (!P_MobjWasRemoved(dust)) + { + P_SetScale(dust, 2*FRACUNIT); + dust->destscale = FRACUNIT/3; + dust->scalespeed = FRACUNIT/40; + dust->fuse = TICRATE*2; + } actor->momx += FixedDiv(dx, dm)*2; actor->momy += FixedDiv(dy, dm)*2; @@ -2693,6 +2712,8 @@ void A_LobShot(mobj_t *actor) z = actor->z + FixedMul(locvar2*FRACUNIT, actor->scale); shot = P_SpawnMobj(actor->x, actor->y, z, locvar1); + if (P_MobjWasRemoved(shot)) + return; if (actor->type == MT_BLACKEGGMAN) { @@ -3074,15 +3095,21 @@ void A_Boss1Laser(mobj_t *actor) S_StartSound(actor, mobjinfo[locvar1].seesound); point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); - point->angle = actor->angle; - point->fuse = dur+1; - P_SetTarget(&point->target, actor->target); - P_SetTarget(&actor->target, point); + if (!P_MobjWasRemoved(point)) + { + point->angle = actor->angle; + point->fuse = dur+1; + P_SetTarget(&point->target, actor->target); + P_SetTarget(&actor->target, point); + } } angle = R_PointToAngle2(z + (mobjinfo[locvar1].height>>1), 0, actor->target->z, R_PointToDist2(x, y, actor->target->x, actor->target->y)); point = P_SpawnMobj(x, y, z, locvar1); + if (P_MobjWasRemoved(point)) + return; + P_SetTarget(&point->target, actor); point->angle = actor->angle; speed = point->radius; @@ -3093,6 +3120,9 @@ void A_Boss1Laser(mobj_t *actor) for (i = 0; i < 256; i++) { mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); + if (P_MobjWasRemoved(mo)) + continue; + mo->angle = point->angle; mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); @@ -3105,9 +3135,12 @@ void A_Boss1Laser(mobj_t *actor) if (mo->info->meleestate) { mobj_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE); - mo2->flags2 |= MF2_LINKDRAW; - P_SetTarget(&mo2->tracer, actor); - P_SetMobjState(mo2, mo->info->meleestate); + if (!P_MobjWasRemoved(mo2)) + { + mo2->flags2 |= MF2_LINKDRAW; + P_SetTarget(&mo2->tracer, actor); + P_SetMobjState(mo2, mo->info->meleestate); + } } } @@ -3125,37 +3158,42 @@ void A_Boss1Laser(mobj_t *actor) if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1) { point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE); - point->angle = actor->angle; - point->destscale = actor->scale; - P_SetScale(point, point->destscale); - P_SetTarget(&point->target, actor); - P_MobjCheckWater(point); - if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) + if (!P_MobjWasRemoved(point)) { - for (i = 0; i < 2; i++) + point->angle = actor->angle; + point->destscale = actor->scale; + P_SetScale(point, point->destscale); + P_SetTarget(&point->target, actor); + P_MobjCheckWater(point); + if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) { - UINT8 size = 3; - mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST); - P_SetScale(steam, size*actor->scale); - P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true); - P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed()); - if (point->info->painsound) - S_StartSound(steam, point->info->painsound); - } - } - else - { - fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius); - fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius); - if (P_TryMove(point, point->x + distx, point->y + disty, false) // prevents the sprite from clipping into the wall or dangling off ledges - && P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false) - && P_TryMove(point, point->x + distx, point->y + disty, false)) - { - if (point->info->seesound) - S_StartSound(point, point->info->seesound); + for (i = 0; i < 2; i++) + { + UINT8 size = 3; + mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST); + if (P_MobjWasRemoved(steam)) + continue; + P_SetScale(steam, size*actor->scale); + P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true); + P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed()); + if (point->info->painsound) + S_StartSound(steam, point->info->painsound); + } } else - P_RemoveMobj(point); + { + fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius); + fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius); + if (P_TryMove(point, point->x + distx, point->y + disty, false) // prevents the sprite from clipping into the wall or dangling off ledges + && P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false) + && P_TryMove(point, point->x + distx, point->y + disty, false)) + { + if (point->info->seesound) + S_StartSound(point, point->info->seesound); + } + else + P_RemoveMobj(point); + } } } @@ -3499,6 +3537,8 @@ void A_BossScream(mobj_t *actor) z = actor->z + FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); mo = P_SpawnMobj(x, y, z, explodetype); + if (P_MobjWasRemoved(mo)) + return; if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; mo->destscale = actor->scale; @@ -3625,6 +3665,9 @@ void A_1upThinker(mobj_t *actor) if (!actor->tracer) { P_SetTarget(&actor->tracer, P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY)); + if (P_MobjWasRemoved(actor->tracer)) + return; + P_SetTarget(&actor->tracer->target, actor); actor->tracer->skin = &skins[players[closestplayer].skin]; // required here to prevent spr2 default showing stand for a single frame P_SetMobjState(actor->tracer, actor->info->seestate); @@ -3686,31 +3729,40 @@ void A_MonitorPop(mobj_t *actor) return; } - newmobj = P_SpawnMobjFromMobj(actor, 0, 0, 13*FRACUNIT, item); - P_SetTarget(&newmobj->target, actor->target); // Transfer target - if (item == MT_1UP_ICON) { if (actor->tracer) // Remove the old lives icon. P_RemoveMobj(actor->tracer); + } - if (!newmobj->target - || !newmobj->target->player - || !newmobj->target->skin - || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0) - {} // No lives icon for this player, use the default. - else - { // Spawn the lives icon. - mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY); - P_SetTarget(&livesico->target, newmobj); - P_SetTarget(&newmobj->tracer, livesico); + newmobj = P_SpawnMobjFromMobj(actor, 0, 0, 13*FRACUNIT, item); + if (!P_MobjWasRemoved(newmobj)) + { + P_SetTarget(&newmobj->target, actor->target); // Transfer target - livesico->color = newmobj->target->player->mo->color; - livesico->skin = &skins[newmobj->target->player->skin]; - P_SetMobjState(livesico, newmobj->info->seestate); + if (item == MT_1UP_ICON) + { + if (!newmobj->target + || !newmobj->target->player + || !newmobj->target->skin + || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0) + {} // No lives icon for this player, use the default. + else + { // Spawn the lives icon. + mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY); + if (!P_MobjWasRemoved(livesico)) + { + P_SetTarget(&livesico->target, newmobj); + P_SetTarget(&newmobj->tracer, livesico); - // We're using the overlay, so use the overlay 1up sprite (no text) - newmobj->sprite = SPR_TV1P; + livesico->color = newmobj->target->player->mo->color; + livesico->skin = &skins[newmobj->target->player->skin]; + P_SetMobjState(livesico, newmobj->info->seestate); + } + + // We're using the overlay, so use the overlay 1up sprite (no text) + newmobj->sprite = SPR_TV1P; + } } } @@ -3773,30 +3825,36 @@ void A_GoldMonitorPop(mobj_t *actor) // Note: the icon spawns 1 fracunit higher newmobj = P_SpawnMobjFromMobj(actor, 0, 0, 14*FRACUNIT, item); - P_SetTarget(&newmobj->target, actor->target); // Transfer target - - if (item == MT_1UP_ICON) + if (!P_MobjWasRemoved(newmobj)) { - if (actor->tracer) // Remove the old lives icon. - P_RemoveMobj(actor->tracer); + P_SetTarget(&newmobj->target, actor->target); // Transfer target - if (!newmobj->target - || !newmobj->target->player - || !newmobj->target->skin - || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0) - {} // No lives icon for this player, use the default. - else - { // Spawn the lives icon. - mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY); - P_SetTarget(&livesico->target, newmobj); - P_SetTarget(&newmobj->tracer, livesico); + if (item == MT_1UP_ICON) + { + if (actor->tracer) // Remove the old lives icon. + P_RemoveMobj(actor->tracer); - livesico->color = newmobj->target->player->mo->color; - livesico->skin = &skins[newmobj->target->player->skin]; - P_SetMobjState(livesico, newmobj->info->seestate); + if (!newmobj->target + || !newmobj->target->player + || !newmobj->target->skin + || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0) + {} // No lives icon for this player, use the default. + else + { // Spawn the lives icon. + mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY); + if (!P_MobjWasRemoved(livesico)) + { + P_SetTarget(&livesico->target, newmobj); + P_SetTarget(&newmobj->tracer, livesico); - // We're using the overlay, so use the overlay 1up sprite (no text) - newmobj->sprite = SPR_TV1P; + livesico->color = newmobj->target->player->mo->color; + livesico->skin = &skins[newmobj->target->player->skin]; + P_SetMobjState(livesico, newmobj->info->seestate); + } + + // We're using the overlay, so use the overlay 1up sprite (no text) + newmobj->sprite = SPR_TV1P; + } } } @@ -3841,7 +3899,13 @@ void A_GoldMonitorSparkle(mobj_t *actor) yofs = FINECOSINE((ngangle>>ANGLETOFINESHIFT) & FINEMASK) * (actor->radius>>FRACBITS); for (i = FRACUNIT*2; i <= FRACUNIT*3; i += FRACUNIT/2) - P_SetObjectMomZ(P_SpawnMobjFromMobj(actor, xofs, yofs, 0, MT_BOXSPARKLE), i, false); + { + mobj_t *sparkle = P_SpawnMobjFromMobj(actor, xofs, yofs, 0, MT_BOXSPARKLE); + if (P_MobjWasRemoved(sparkle)) + continue; + + P_SetObjectMomZ(sparkle, i, false); + } } // Function: A_Explode @@ -3963,56 +4027,73 @@ static void P_DoBossVictory(mobj_t *mo) static void P_SpawnBoss1Junk(mobj_t *mo) { mobj_t *mo2 = P_SpawnMobjFromMobj(mo, - P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSEGLZ1); + P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; + P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSEGLZ1); + } mo2 = P_SpawnMobjFromMobj(mo, P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSEGLZ2); + if (!P_MobjWasRemoved(mo2)) + { + mo2->angle = mo->angle; + P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSEGLZ2); + } } static void P_SpawnBoss2Junk(mobj_t *mo) { mobj_t *mo2 = P_SpawnMobjFromMobj(mo, - P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSTANK1); + P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; + P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSTANK1); + } mo2 = P_SpawnMobjFromMobj(mo, P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSTANK2); + if (!P_MobjWasRemoved(mo2)) + { + mo2->angle = mo->angle; + P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSTANK2); + } mo2 = P_SpawnMobjFromMobj(mo, 0, 0, mobjinfo[MT_EGGMOBILE2].height + (32<angle = mo->angle; - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - mo2->momz += mo->momz; - P_SetMobjState(mo2, S_BOSSSPIGOT); + if (!P_MobjWasRemoved(mo2)) + { + mo2->angle = mo->angle; + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + mo2->momz += mo->momz; + P_SetMobjState(mo2, S_BOSSSPIGOT); + } } static void P_SpawnBoss3Junk(mobj_t *mo) { mobj_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK); + if (P_MobjWasRemoved(mo2)) + return; mo2->angle = mo->angle; P_SetMobjState(mo2, S_BOSSSEBH1); } @@ -4052,26 +4133,36 @@ static void P_DoBoss5Death(mobj_t *mo) mo->tracer->y - P_ReturnThrustY(mo->tracer, mo->tracer->angle, speed*time), mo->tracer->floorz + (256+1)*FRACUNIT, MT_FSGNB); - P_SetTarget(&pole->tracer, P_SpawnMobj( - pole->x, pole->y, - pole->z - 256*FRACUNIT, - MT_FSGNB)); - P_SetTarget(&pole->tracer->tracer, P_SpawnMobj( - pole->x + P_ReturnThrustX(pole, mo->tracer->angle, FRACUNIT), - pole->y + P_ReturnThrustY(pole, mo->tracer->angle, FRACUNIT), - pole->z + 256*FRACUNIT, - MT_FSGNA)); - pole->tracer->flags |= MF_NOCLIPTHING; - P_SetScale(pole, (pole->destscale = 2*FRACUNIT)); - P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT)); - pole->angle = pole->tracer->angle = mo->tracer->angle; - pole->tracer->tracer->angle = pole->angle - ANGLE_90; - pole->momx = P_ReturnThrustX(pole, pole->angle, speed); - pole->momy = P_ReturnThrustY(pole, pole->angle, speed); - pole->tracer->momx = pole->momx; - pole->tracer->momy = pole->momy; - pole->tracer->tracer->momx = pole->momx; - pole->tracer->tracer->momy = pole->momy; + if (!P_MobjWasRemoved(pole)) + { + P_SetScale(pole, (pole->destscale = 2*FRACUNIT)); + pole->momx = P_ReturnThrustX(pole, pole->angle, speed); + pole->momy = P_ReturnThrustY(pole, pole->angle, speed); + P_SetTarget(&pole->tracer, P_SpawnMobj( + pole->x, pole->y, + pole->z - 256*FRACUNIT, + MT_FSGNB)); + if (!P_MobjWasRemoved(pole->tracer)) + { + pole->tracer->flags |= MF_NOCLIPTHING; + P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT)); + pole->angle = pole->tracer->angle = mo->tracer->angle; + pole->tracer->momx = pole->momx; + pole->tracer->momy = pole->momy; + + P_SetTarget(&pole->tracer->tracer, P_SpawnMobj( + pole->x + P_ReturnThrustX(pole, mo->tracer->angle, FRACUNIT), + pole->y + P_ReturnThrustY(pole, mo->tracer->angle, FRACUNIT), + pole->z + 256*FRACUNIT, + MT_FSGNA)); + if (!P_MobjWasRemoved(pole->tracer->tracer)) + { + pole->tracer->tracer->angle = pole->angle - ANGLE_90; + pole->tracer->tracer->momx = pole->momx; + pole->tracer->tracer->momy = pole->momy; + } + } + } } } else @@ -4731,9 +4822,12 @@ void A_AttractChase(mobj_t *actor) { mobj_t *newring; newring = P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->reactiontime); - newring->momx = actor->momx; - newring->momy = actor->momy; - newring->momz = actor->momz; + if (!P_MobjWasRemoved(newring)) + { + newring->momx = actor->momx; + newring->momy = actor->momy; + newring->momz = actor->momz; + } P_RemoveMobj(actor); return; } @@ -4813,9 +4907,12 @@ void A_DropMine(mobj_t *actor) // Use raisestate instead of MT_MINE mine = P_SpawnMobj(actor->x, actor->y, z, (mobjtype_t)actor->info->raisestate); - if (actor->eflags & MFE_VERTICALFLIP) - mine->eflags |= MFE_VERTICALFLIP; - mine->momz = actor->momz + actor->pmomz; + if (!P_MobjWasRemoved(mine)) + { + if (actor->eflags & MFE_VERTICALFLIP) + mine->eflags |= MFE_VERTICALFLIP; + mine->momz = actor->momz + actor->pmomz; + } S_StartSound(actor, actor->info->attacksound); } @@ -5138,11 +5235,13 @@ void A_SignSpin(mobj_t *actor) if (actor->tracer == NULL || P_MobjWasRemoved(actor->tracer)) return; for (i = -1; i < 2; i += 2) { - P_SpawnMobjFromMobj(actor, + mobj_t *spinmobj = P_SpawnMobjFromMobj(actor, P_ReturnThrustX(actor, actor->tracer->angle, i * actor->radius), P_ReturnThrustY(actor, actor->tracer->angle, i * actor->radius), (actor->eflags & MFE_VERTICALFLIP) ? 0 : actor->height, - actor->info->painchance)->destscale >>= 1; + actor->info->painchance); + if (!P_MobjWasRemoved(spinmobj)) + spinmobj->destscale >>= 1; } } @@ -5202,8 +5301,11 @@ void A_SignPlayer(mobj_t *actor) if (actor->tracer->tracer == NULL || P_MobjWasRemoved(actor->tracer->tracer)) { ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); - P_SetTarget(&ov->target, actor->tracer); - P_SetTarget(&actor->tracer->tracer, ov); + if (!P_MobjWasRemoved(ov)) + { + P_SetTarget(&ov->target, actor->tracer); + P_SetTarget(&actor->tracer->tracer, ov); + } } else ov = actor->tracer->tracer; @@ -5263,33 +5365,36 @@ void A_SignPlayer(mobj_t *actor) signcolor = skincolors[facecolor].invcolor; } - if (skin) - { - if (skin->sprites[SPR2_SIGN].numframes) // player face + if (!P_MobjWasRemoved(ov)) + { + if (skin) { - ov->color = facecolor; - ov->skin = skin; - if ((statenum_t)(ov->state-states) != actor->info->seestate) - P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN + if (skin->sprites[SPR2_SIGN].numframes) // player face + { + ov->color = facecolor; + ov->skin = skin; + if ((statenum_t)(ov->state-states) != actor->info->seestate) + P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN + } + else // CLEAR! sign + { + ov->color = SKINCOLOR_NONE; + ov->skin = NULL; // needs to be NULL in the case of SF_HIRES characters + if ((statenum_t)(ov->state-states) != actor->info->missilestate) + P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN + } } - else // CLEAR! sign + else // Eggman face { ov->color = SKINCOLOR_NONE; - ov->skin = NULL; // needs to be NULL in the case of SF_HIRES characters - if ((statenum_t)(ov->state-states) != actor->info->missilestate) - P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN + ov->skin = NULL; + if ((statenum_t)(ov->state-states) != actor->info->meleestate) + P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN + if (!signcolor) + signcolor = SKINCOLOR_CARBON; + facecolor = signcolor; } - } - else // Eggman face - { - ov->color = SKINCOLOR_NONE; - ov->skin = NULL; - if ((statenum_t)(ov->state-states) != actor->info->meleestate) - P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN - if (!signcolor) - signcolor = SKINCOLOR_CARBON; - facecolor = signcolor; - } + } actor->tracer->color = signcolor; if (signcolor && signcolor < numskincolors) @@ -5480,12 +5585,14 @@ void A_JetbThink(mobj_t *actor) // use raisestate instead of MT_MINE bomb = P_SpawnMobj(actor->x, actor->y, actor->z - FixedMul((32<scale), (mobjtype_t)actor->info->raisestate); - - P_SetTarget(&bomb->target, actor); - bomb->destscale = actor->scale; - P_SetScale(bomb, actor->scale); - actor->reactiontime = TICRATE; // one second - S_StartSound(actor, actor->info->attacksound); + if (!P_MobjWasRemoved(bomb)) + { + P_SetTarget(&bomb->target, actor); + bomb->destscale = actor->scale; + P_SetScale(bomb, actor->scale); + actor->reactiontime = TICRATE; // one second + S_StartSound(actor, actor->info->attacksound); + } } } else if (((actor->z - FixedMul((32<scale)) < thefloor) && !((thefloor + FixedMul((32<scale) + actor->height) > actor->ceilingz)) @@ -5631,9 +5738,12 @@ void A_MinusDigging(mobj_t *actor) } par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); - if (actor->eflags & MFE_VERTICALFLIP) - par->eflags |= MFE_VERTICALFLIP; - P_TryMove(par, x, y, false); + if (!P_MobjWasRemoved(par)) + { + if (actor->eflags & MFE_VERTICALFLIP) + par->eflags |= MFE_VERTICALFLIP; + P_TryMove(par, x, y, false); + } // If close enough, prepare to attack if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) @@ -5644,6 +5754,8 @@ void A_MinusDigging(mobj_t *actor) // Spawn growing dirt pile. par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); + if (P_MobjWasRemoved(par)) + return; P_SetMobjState(par, actor->info->raisestate); P_SetScale(par, actor->scale*2); if (actor->eflags & MFE_VERTICALFLIP) @@ -5714,6 +5826,8 @@ void A_MinusPopup(mobj_t *actor) for (i = 1; i <= num; i++) { mobj_t *rock = P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_ROCKCRUMBLE1); + if (P_MobjWasRemoved(rock)) + continue; P_Thrust(rock, ani*i, FRACUNIT); P_SetObjectMomZ(rock, 3*FRACUNIT, false); P_SetScale(rock, rock->scale/3); @@ -5751,6 +5865,8 @@ void A_MinusCheck(mobj_t *actor) for (i = 1; i <= num; i++) { mobj_t *rock = P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_ROCKCRUMBLE1); + if (P_MobjWasRemoved(rock)) + continue; P_Thrust(rock, ani*i, FRACUNIT); P_SetObjectMomZ(rock, 3*FRACUNIT, false); P_SetScale(rock, rock->scale/3); @@ -6262,6 +6378,8 @@ void A_RockSpawn(mobj_t *actor) dist += actor->spawnpoint->args[2] ? P_RandomByte() * (FRACUNIT/32) : 0; // random oomph mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FALLINGROCK); + if (P_MobjWasRemoved(mo)) + return; P_SetMobjState(mo, mobjinfo[type].spawnstate); mo->angle = FixedAngle(actor->spawnpoint->angle << FRACBITS); @@ -6298,6 +6416,8 @@ void A_SlingAppear(mobj_t *actor) actor->friction = 128; hprev = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLGRABCHAIN); + if (P_MobjWasRemoved(hprev)) + return; P_SetTarget(&hprev->tracer, actor); P_SetTarget(&hprev->hprev, actor); P_SetTarget(&actor->hnext, hprev); @@ -6309,13 +6429,16 @@ void A_SlingAppear(mobj_t *actor) while (mlength > 0) { spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN); - P_SetTarget(&spawnee->tracer, actor); - P_SetTarget(&spawnee->hprev, hprev); - P_SetTarget(&hprev->hnext, spawnee); - hprev = spawnee; + if (!P_MobjWasRemoved(spawnee)) + { + P_SetTarget(&spawnee->tracer, actor); + P_SetTarget(&spawnee->hprev, hprev); + P_SetTarget(&hprev->hnext, spawnee); + hprev = spawnee; - spawnee->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; - spawnee->movecount = mlength; + spawnee->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; + spawnee->movecount = mlength; + } mlength--; } @@ -6575,6 +6698,8 @@ void A_OldRingExplode(mobj_t *actor) { const angle_t fa = (i*FINEANGLES/16) & FINEMASK; mo = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1); + if (P_MobjWasRemoved(mo)) + continue; P_SetTarget(&mo->target, actor->target); // Transfer target so player gets the points mo->momx = FixedMul(FINECOSINE(fa),ns); @@ -6601,33 +6726,37 @@ void A_OldRingExplode(mobj_t *actor) { } mo = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1); - - P_SetTarget(&mo->target, actor->target); - mo->momz = ns; - mo->flags2 |= MF2_DEBRIS; - mo->fuse = TICRATE/5; - - if (changecolor) + if (!P_MobjWasRemoved(mo)) { - if (!(gametyperules & GTR_TEAMS)) - mo->color = actor->target->color; //copy color - else if (actor->target->player->ctfteam == 2) - mo->color = skincolor_bluering; + P_SetTarget(&mo->target, actor->target); + mo->momz = ns; + mo->flags2 |= MF2_DEBRIS; + mo->fuse = TICRATE/5; + + if (changecolor) + { + if (!(gametyperules & GTR_TEAMS)) + mo->color = actor->target->color; //copy color + else if (actor->target->player->ctfteam == 2) + mo->color = skincolor_bluering; + } } mo = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1); - - P_SetTarget(&mo->target, actor->target); - mo->momz = -ns; - mo->flags2 |= MF2_DEBRIS; - mo->fuse = TICRATE/5; - - if (changecolor) + if (!P_MobjWasRemoved(mo)) { - if (!(gametyperules & GTR_TEAMS)) - mo->color = actor->target->color; //copy color - else if (actor->target->player->ctfteam == 2) - mo->color = skincolor_bluering; + P_SetTarget(&mo->target, actor->target); + mo->momz = -ns; + mo->flags2 |= MF2_DEBRIS; + mo->fuse = TICRATE/5; + + if (changecolor) + { + if (!(gametyperules & GTR_TEAMS)) + mo->color = actor->target->color; //copy color + else if (actor->target->player->ctfteam == 2) + mo->color = skincolor_bluering; + } } } @@ -7263,23 +7392,26 @@ void A_Boss2Chase(mobj_t *actor) fa = (actor->movedir*FINEANGLES/8) & FINEMASK; goop = P_SpawnMobj(actor->x, actor->y, fz, actor->info->painchance); - goop->momx = FixedMul(FINECOSINE(fa),ns); - goop->momy = FixedMul(FINESINE(fa),ns); - goop->momz = FixedMul(4*FRACUNIT, actor->scale); - goop->fuse = 10*TICRATE; - - if (actor->info->attacksound) - S_StartAttackSound(actor, actor->info->attacksound); - - if (P_RandomChance(FRACUNIT/2)) + if (!P_MobjWasRemoved(goop)) { - goop->momx *= 2; - goop->momy *= 2; - } - else if (P_RandomChance(129*FRACUNIT/256)) - { - goop->momx *= 3; - goop->momy *= 3; + goop->momx = FixedMul(FINECOSINE(fa),ns); + goop->momy = FixedMul(FINESINE(fa),ns); + goop->momz = FixedMul(4*FRACUNIT, actor->scale); + goop->fuse = 10*TICRATE; + + if (actor->info->attacksound) + S_StartAttackSound(actor, actor->info->attacksound); + + if (P_RandomChance(FRACUNIT/2)) + { + goop->momx *= 2; + goop->momy *= 2; + } + else if (P_RandomChance(129*FRACUNIT/256)) + { + goop->momx *= 3; + goop->momy *= 3; + } } actor->flags2 |= MF2_JUSTATTACKED; @@ -7320,6 +7452,8 @@ void A_Boss2Pogo(mobj_t *actor) fa = (actor->movedir*FINEANGLES/8) & FINEMASK; goop = P_SpawnMobj(actor->x, actor->y, fz, actor->info->painchance); + if (P_MobjWasRemoved(goop)) + continue; goop->momx = FixedMul(FINECOSINE(fa),ns); goop->momy = FixedMul(FINESINE(fa),ns); goop->momz = FixedMul(4*FRACUNIT, actor->scale); @@ -7640,7 +7774,8 @@ void A_Boss2PogoTarget(mobj_t *actor) if (actor->info->missilestate) // spawn the pogo stick collision box { mobj_t *pogo = P_SpawnMobj(actor->x, actor->y, actor->z - mobjinfo[actor->info->missilestate].height, (mobjtype_t)actor->info->missilestate); - P_SetTarget(&pogo->target, actor); + if (!P_MobjWasRemoved(pogo)) + P_SetTarget(&pogo->target, actor); } actor->reactiontime = 1; @@ -8131,6 +8266,8 @@ void A_Boss1Spikeballs(mobj_t *actor) return; ball = P_SpawnMobj(actor->x, actor->y, actor->z, MT_EGGMOBILE_BALL); + if (P_MobjWasRemoved(ball)) + return; P_SetTarget(&ball->target, actor); ball->movedir = FixedAngle(FixedMul(FixedDiv(locvar1<threshold = ball->radius + actor->radius + ball->info->painchance; @@ -8315,19 +8452,22 @@ void A_Boss3ShockThink(mobj_t *actor) snew = P_SpawnMobj((x0 >> 1) + (x1 >> 1), (y0 >> 1) + (y1 >> 1), (actor->z >> 1) + (snext->z >> 1), actor->type); - snew->momx = (actor->momx + snext->momx) >> 1; - snew->momy = (actor->momy + snext->momy) >> 1; - snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed? - snew->angle = (actor->angle + snext->angle) >> 1; - P_SetTarget(&snew->target, actor->target); - snew->fuse = actor->fuse; + if (!P_MobjWasRemoved(snew)) + { + snew->momx = (actor->momx + snext->momx) >> 1; + snew->momy = (actor->momy + snext->momy) >> 1; + snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed? + snew->angle = (actor->angle + snext->angle) >> 1; + P_SetTarget(&snew->target, actor->target); + snew->fuse = actor->fuse; - P_SetScale(snew, actor->scale); - snew->destscale = actor->destscale; - snew->scalespeed = actor->scalespeed; + P_SetScale(snew, actor->scale); + snew->destscale = actor->destscale; + snew->scalespeed = actor->scalespeed; - P_SetTarget(&actor->hnext, snew); - P_SetTarget(&snew->hnext, snext); + P_SetTarget(&actor->hnext, snew); + P_SetTarget(&snew->hnext, snext); + } } } } @@ -8462,10 +8602,13 @@ void A_SmokeTrailer(mobj_t *actor) if (actor->eflags & MFE_VERTICALFLIP) { th = P_SpawnMobj(actor->x-actor->momx, actor->y-actor->momy, actor->z + actor->height - FixedMul(mobjinfo[locvar1].height, actor->scale), locvar1); - th->flags2 |= MF2_OBJECTFLIP; + if (!P_MobjWasRemoved(th)) + th->flags2 |= MF2_OBJECTFLIP; } else th = P_SpawnMobj(actor->x-actor->momx, actor->y-actor->momy, actor->z, locvar1); + if (P_MobjWasRemoved(th)) + return; P_SetObjectMomZ(th, FRACUNIT, false); th->destscale = actor->scale; P_SetScale(th, actor->scale); @@ -8502,6 +8645,8 @@ void A_SpawnObjectAbsolute(mobj_t *actor) type = (mobjtype_t)(locvar2&65535); mo = P_SpawnMobj(x<angle = actor->angle; @@ -8544,6 +8689,8 @@ void A_SpawnObjectRelative(mobj_t *actor) mo = P_SpawnMobj(actor->x + FixedMul(x<scale), actor->y + FixedMul(y<scale), (actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[type].height) - FixedMul(z<scale)) : (actor->z + FixedMul(z<scale)), type); + if (P_MobjWasRemoved(mo)) + return; // Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn mo->angle = actor->angle; @@ -9205,12 +9352,15 @@ void A_BossJetFume(mobj_t *actor) jetz = actor->z + FixedMul(38*FRACUNIT, actor->scale); filler = P_SpawnMobj(jetx, jety, jetz, MT_JETFUME1); - P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); - if (actor->eflags & MFE_VERTICALFLIP) - filler->flags2 |= MF2_OBJECTFLIP; - filler->fuse = 56; + if (!P_MobjWasRemoved(filler)) + { + P_SetTarget(&filler->target, actor); + filler->destscale = actor->scale; + P_SetScale(filler, filler->destscale); + if (actor->eflags & MFE_VERTICALFLIP) + filler->flags2 |= MF2_OBJECTFLIP; + filler->fuse = 56; + } if (actor->eflags & MFE_VERTICALFLIP) jetz = actor->z + actor->height - FixedMul(12*FRACUNIT + mobjinfo[MT_JETFUME1].height, actor->scale); @@ -9220,22 +9370,28 @@ void A_BossJetFume(mobj_t *actor) filler = P_SpawnMobj(jetx + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(24*FRACUNIT, actor->scale)), jety + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(24*FRACUNIT, actor->scale)), jetz, MT_JETFUME1); - P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); - if (actor->eflags & MFE_VERTICALFLIP) - filler->flags2 |= MF2_OBJECTFLIP; - filler->fuse = 57; + if (!P_MobjWasRemoved(filler)) + { + P_SetTarget(&filler->target, actor); + filler->destscale = actor->scale; + P_SetScale(filler, filler->destscale); + if (actor->eflags & MFE_VERTICALFLIP) + filler->flags2 |= MF2_OBJECTFLIP; + filler->fuse = 57; + } filler = P_SpawnMobj(jetx + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(24*FRACUNIT, actor->scale)), jety + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(24*FRACUNIT, actor->scale)), jetz, MT_JETFUME1); - P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); - if (actor->eflags & MFE_VERTICALFLIP) - filler->flags2 |= MF2_OBJECTFLIP; - filler->fuse = 58; + if (!P_MobjWasRemoved(filler)) + { + P_SetTarget(&filler->target, actor); + filler->destscale = actor->scale; + P_SetScale(filler, filler->destscale); + if (actor->eflags & MFE_VERTICALFLIP) + filler->flags2 |= MF2_OBJECTFLIP; + filler->fuse = 58; + } P_SetTarget(&actor->tracer, filler); } @@ -9263,14 +9419,17 @@ void A_BossJetFume(mobj_t *actor) else if (locvar1 == 2) // Metal Sonic jet fumes { filler = P_SpawnMobj(actor->x, actor->y, actor->z, MT_JETFUME1); - P_SetTarget(&filler->target, actor); - filler->fuse = 59; - P_SetTarget(&actor->tracer, filler); - P_SetScale(filler, (filler->destscale = actor->scale/3)); - if (actor->eflags & MFE_VERTICALFLIP) - filler->flags2 |= MF2_OBJECTFLIP; - filler->color = SKINCOLOR_ICY; - filler->colorized = true; + if (!P_MobjWasRemoved(filler)) + { + P_SetTarget(&filler->target, actor); + filler->fuse = 59; + P_SetTarget(&actor->tracer, filler); + P_SetScale(filler, (filler->destscale = actor->scale/3)); + if (actor->eflags & MFE_VERTICALFLIP) + filler->flags2 |= MF2_OBJECTFLIP; + filler->color = SKINCOLOR_ICY; + filler->colorized = true; + } } else if (locvar1 == 3) // Boss 4 jet flame { @@ -9280,12 +9439,15 @@ void A_BossJetFume(mobj_t *actor) else jetz = actor->z - 50*actor->scale; filler = P_SpawnMobj(actor->x, actor->y, jetz, MT_JETFLAME); - P_SetTarget(&filler->target, actor); - // Boss 4 already uses its tracer for other things - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); - if (actor->eflags & MFE_VERTICALFLIP) - filler->flags2 |= MF2_OBJECTFLIP; + if (!P_MobjWasRemoved(filler)) + { + P_SetTarget(&filler->target, actor); + // Boss 4 already uses its tracer for other things + filler->destscale = actor->scale; + P_SetScale(filler, filler->destscale); + if (actor->eflags & MFE_VERTICALFLIP) + filler->flags2 |= MF2_OBJECTFLIP; + } } else if (locvar1 == 4) // Boss 4 Spectator Eggrobo jet flame { @@ -9300,12 +9462,15 @@ void A_BossJetFume(mobj_t *actor) jetx = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, movefactor*actor->scale) - P_ReturnThrustX(actor, actor->angle, 19*actor->scale); jety = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, movefactor*actor->scale) - P_ReturnThrustY(actor, actor->angle, 19*actor->scale); filler = P_SpawnMobj(jetx, jety, jetz, MT_EGGROBO1JET); - filler->movefactor = movefactor; - P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); - if (actor->eflags & MFE_VERTICALFLIP) - filler->flags2 |= MF2_OBJECTFLIP; + if (!P_MobjWasRemoved(filler)) + { + filler->movefactor = movefactor; + P_SetTarget(&filler->target, actor); + filler->destscale = actor->scale; + P_SetScale(filler, filler->destscale); + if (actor->eflags & MFE_VERTICALFLIP) + filler->flags2 |= MF2_OBJECTFLIP; + } if (movefactor <= 0) break; movefactor = -movefactor; @@ -11007,6 +11172,8 @@ void A_TrapShot(mobj_t *actor) type, frontoff, (INT16)(locvar2 & 65535), vertoff); missile = P_SpawnMobj(x, y, z, type); + if (P_MobjWasRemoved(missile)) + return; if (actor->eflags & MFE_VERTICALFLIP) missile->flags2 |= MF2_OBJECTFLIP; @@ -11077,18 +11244,21 @@ void A_VileTarget(mobj_t *actor) actor->target->y, actor->target->z + ((actor->target->eflags & MFE_VERTICALFLIP) ? actor->target->height - mobjinfo[fogtype].height : 0), fogtype); - if (actor->target->eflags & MFE_VERTICALFLIP) + if (!P_MobjWasRemoved(fog)) { - fog->eflags |= MFE_VERTICALFLIP; - fog->flags2 |= MF2_OBJECTFLIP; - } - fog->destscale = actor->target->scale; - P_SetScale(fog, fog->destscale); + if (actor->target->eflags & MFE_VERTICALFLIP) + { + fog->eflags |= MFE_VERTICALFLIP; + fog->flags2 |= MF2_OBJECTFLIP; + } + fog->destscale = actor->target->scale; + P_SetScale(fog, fog->destscale); - P_SetTarget(&actor->tracer, fog); - P_SetTarget(&fog->target, actor); - P_SetTarget(&fog->tracer, actor->target); - A_VileFire(fog); + P_SetTarget(&actor->tracer, fog); + P_SetTarget(&fog->target, actor); + P_SetTarget(&fog->tracer, actor->target); + A_VileFire(fog); + } } else { @@ -11108,19 +11278,22 @@ void A_VileTarget(mobj_t *actor) players[i].mo->y, players[i].mo->z + ((players[i].mo->eflags & MFE_VERTICALFLIP) ? players[i].mo->height - mobjinfo[fogtype].height : 0), fogtype); - if (players[i].mo->eflags & MFE_VERTICALFLIP) + if (!P_MobjWasRemoved(fog)) { - fog->eflags |= MFE_VERTICALFLIP; - fog->flags2 |= MF2_OBJECTFLIP; - } - fog->destscale = players[i].mo->scale; - P_SetScale(fog, fog->destscale); + if (players[i].mo->eflags & MFE_VERTICALFLIP) + { + fog->eflags |= MFE_VERTICALFLIP; + fog->flags2 |= MF2_OBJECTFLIP; + } + fog->destscale = players[i].mo->scale; + P_SetScale(fog, fog->destscale); - if (players[i].mo == actor->target) // We only care to track the fog targeting who we REALLY hate right now - P_SetTarget(&actor->tracer, fog); - P_SetTarget(&fog->target, actor); - P_SetTarget(&fog->tracer, players[i].mo); - A_VileFire(fog); + if (players[i].mo == actor->target) // We only care to track the fog targeting who we REALLY hate right now + P_SetTarget(&actor->tracer, fog); + P_SetTarget(&fog->target, actor); + P_SetTarget(&fog->tracer, players[i].mo); + A_VileFire(fog); + } } } } @@ -11590,6 +11763,8 @@ void A_BrakLobShot(mobj_t *actor) typeOfShot = MT_CANNONBALL; else typeOfShot = (mobjtype_t)locvar1; shot = P_SpawnMobj(actor->x, actor->y, actor->z + FixedMul(locvar2*FRACUNIT, actor->scale), typeOfShot); + if (P_MobjWasRemoved(shot)) + return; if (shot->info->seesound) S_StartSound(shot, shot->info->seesound); P_SetTarget(&shot->target, actor); // where it came from @@ -11656,6 +11831,8 @@ void A_NapalmScatter(mobj_t *actor) const angle_t fa = (i*FINEANGLES/numToShoot) & FINEMASK; mo = P_SpawnMobj(actor->x, actor->y, actor->z, typeOfShot); + if (P_MobjWasRemoved(mo)) + continue; P_SetTarget(&mo->target, actor->target); // Transfer target so Brak doesn't hit himself like an idiot mo->angle = fa << ANGLETOFINESHIFT; @@ -11681,6 +11858,8 @@ void A_SpawnFreshCopy(mobj_t *actor) return; newObject = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->type); + if (P_MobjWasRemoved(newObject)) + return; newObject->flags2 = actor->flags2 & MF2_AMBUSH; newObject->angle = actor->angle; newObject->color = actor->color; @@ -11716,6 +11895,8 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz } flicky = P_SpawnMobjFromMobj(actor, offsx, offsy, 0, flickytype); + if (P_MobjWasRemoved(flicky)) + return NULL; flicky->angle = actor->angle; if (flickytype == MT_SEED) @@ -11827,8 +12008,11 @@ void A_FlickyCenter(mobj_t *actor) if (!actor->tracer) { mobj_t *flicky = P_InternalFlickySpawn(actor, locvar1, 1, false, 0); - P_SetTarget(&flicky->target, actor); - P_SetTarget(&actor->tracer, flicky); + if (!P_MobjWasRemoved(flicky)) + { + P_SetTarget(&flicky->target, actor); + P_SetTarget(&actor->tracer, flicky); + } if (actor->spawnpoint) { @@ -11863,18 +12047,21 @@ void A_FlickyCenter(mobj_t *actor) locvar1 = flickytype; } - if (actor->flags & MF_GRENADEBOUNCE) // in-place - actor->tracer->fuse = 0; - else if (actor->flags & MF_SLIDEME) // aimless + if (!P_MobjWasRemoved(flicky)) { - actor->tracer->fuse = 0; // less than 2*TICRATE means move aimlessly. - actor->tracer->angle = P_RandomKey(180)*ANG2; - } - else //orbit - actor->tracer->fuse = FRACUNIT; + if (actor->flags & MF_GRENADEBOUNCE) // in-place + actor->tracer->fuse = 0; + else if (actor->flags & MF_SLIDEME) // aimless + { + actor->tracer->fuse = 0; // less than 2*TICRATE means move aimlessly. + actor->tracer->angle = P_RandomKey(180)*ANG2; + } + else //orbit + actor->tracer->fuse = FRACUNIT; - if (locvar1 == MT_FLICKY_08) - P_InternalFlickySetColor(actor->tracer, actor->extravalue2); + if (locvar1 == MT_FLICKY_08) + P_InternalFlickySetColor(actor->tracer, actor->extravalue2); + } actor->extravalue2 = 0; } @@ -11885,7 +12072,8 @@ void A_FlickyCenter(mobj_t *actor) fixed_t originy = actor->movefactor; fixed_t originz = actor->watertop; - actor->tracer->fuse = FRACUNIT; + if (!P_MobjWasRemoved(actor->tracer)) + actor->tracer->fuse = FRACUNIT; // Impose default home radius if flicky orbits around player if (!actor->extravalue1) @@ -11917,6 +12105,8 @@ void P_InternalFlickyBubble(mobj_t *actor) return; overlay = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); + if (P_MobjWasRemoved(overlay)) + return; P_SetMobjStateNF(overlay, mobjinfo[actor->type].raisestate); P_SetTarget(&actor->tracer, overlay); P_SetTarget(&overlay->target, actor); @@ -12291,7 +12481,8 @@ void A_FlameParticle(mobj_t *actor) P_RandomRange(rad, -rad)<frame = actor->frame; if (!(locvar1 & 1)) @@ -12477,6 +12670,8 @@ void A_MineExplode(mobj_t *actor) actor->y+P_RandomRange(-dist, dist)*FRACUNIT, actor->z+P_RandomRange(((actor->eflags & MFE_UNDERWATER) ? -dist : 0), dist)*FRACUNIT, type); + if (P_MobjWasRemoved(b)) + continue; fixed_t dx = b->x - actor->x, dy = b->y - actor->y, dz = b->z - actor->z; fixed_t dm = P_AproxDistance(dz, P_AproxDistance(dy, dx)); b->momx = FixedDiv(dx, dm)*3; @@ -12605,6 +12800,8 @@ void A_SpawnParticleRelative(mobj_t *actor) mo = P_SpawnMobj(actor->x + FixedMul(x<scale), actor->y + FixedMul(y<scale), (actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[MT_PARTICLE].height) - FixedMul(z<scale)) : (actor->z + FixedMul(z<scale)), MT_PARTICLE); + if (P_MobjWasRemoved(mo)) + return; // Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn mo->angle = actor->angle; @@ -12997,11 +13194,14 @@ void A_DoNPCSkid(mobj_t *actor) if (!(leveltime % 3)) { mobj_t *particle = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_SPINDUST); - particle->tics = 10; + if (!P_MobjWasRemoved(particle)) + { + particle->tics = 10; - P_SetScale(particle, 2*actor->scale/3); - particle->destscale = actor->scale; - P_SetObjectMomZ(particle, FRACUNIT, false); + P_SetScale(particle, 2*actor->scale/3); + particle->destscale = actor->scale; + P_SetObjectMomZ(particle, FRACUNIT, false); + } } } @@ -13304,11 +13504,18 @@ void A_Boss5MakeJunk(mobj_t *actor) if (actor->extravalue2 > 10) { mobj_t *front = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_VWREF); - broked = P_SpawnMobjFromMobj(front, 0, 0, 0, MT_VWREB); - front->z = broked->z = front->z - broked->height; - P_SetObjectMomZ(front, (4<momz = front->momz; - broked->fuse = front->fuse = (actor->height+(2*front->height))/front->momz; + if (!P_MobjWasRemoved(front)) + { + P_SetObjectMomZ(front, (4<z -= broked->height; + broked->z = front->z; + broked->momz = front->momz; + broked->fuse = front->fuse = (actor->height+(2*front->height))/front->momz; + } + } } if (!(actor->colorized = !actor->colorized)) actor->frame |= FF_FULLBRIGHT; @@ -13322,6 +13529,8 @@ void A_Boss5MakeJunk(mobj_t *actor) while (i--) { broked = P_SpawnMobjFromMobj(actor, 0, 0, FRACUNIT, MT_BROKENROBOT); + if (P_MobjWasRemoved(broked)) + continue; if (locvar2 & 2) broked->fuse = TICRATE; else @@ -13339,13 +13548,17 @@ void A_Boss5MakeJunk(mobj_t *actor) if (locvar2 & 2) { broked = P_SpawnMobjFromMobj(actor, 0, 0, 64<fuse = states[S_FANG_INTRO12].tics+10; - P_SetMobjState(broked, S_ALART1); + if (!P_MobjWasRemoved(broked)) + { + S_StartSound(broked, sfx_alart); + broked->fuse = states[S_FANG_INTRO12].tics+10; + P_SetMobjState(broked, S_ALART1); + } } else if (locvar2 & 1) { - broked->z += broked->momz; + if (!P_MobjWasRemoved(broked)) + broked->z += broked->momz; S_StartSound(actor, sfx_s3kccs); actor->flags &= ~MF_NOCLIPTHING; } @@ -13404,6 +13617,8 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi z, mobjtype ); + if (P_MobjWasRemoved(dust)) + continue; dust->angle = ang*i + ANGLE_90; P_SetScale(dust, FixedMul(initscale, scale)); @@ -13556,9 +13771,12 @@ void A_DustDevilThink(mobj_t *actor) if (P_IsObjectOnGround(actor)) { angle_t dustang = ((P_RandomRange(0, 7)*ANGLE_45)>>ANGLETOFINESHIFT) & FINEMASK; mobj_t *dust = P_SpawnMobj(actor->x + 96 * FixedMul(scale, FINECOSINE(dustang)), actor->y + 96 * FixedMul(scale, FINESINE(dustang)), actor->z, MT_ARIDDUST); - P_SetMobjState(dust, dust->info->spawnstate + P_RandomRange(0, 2)); - dust->destscale = scale * 3; - P_SetScale(dust, dust->destscale); + if (!P_MobjWasRemoved(dust)) + { + P_SetMobjState(dust, dust->info->spawnstate + P_RandomRange(0, 2)); + dust->destscale = scale * 3; + P_SetScale(dust, dust->destscale); + } } actor->extravalue1++; @@ -13574,6 +13792,8 @@ void A_DustDevilThink(mobj_t *actor) fixed_t pz = actor->z; layer = P_SpawnMobj(px, py, pz, MT_DUSTLAYER); + if (P_MobjWasRemoved(layer)) + continue; layer->momz = 5 * scale; layer->angle = ANGLE_90 + ANGLE_90*i; layer->extravalue1 = TICRATE * 3; @@ -13759,6 +13979,8 @@ void A_DebrisRandom(mobj_t *actor) static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t ang, spritenum_t spr, UINT32 frame) { mobj_t *s = P_SpawnMobj(x, y, z, MT_TRAINSEG); + if (P_MobjWasRemoved(s)) + return NULL; s->fuse = 16*TICRATE; s->sprite = spr; s->frame = frame|FF_PAPERSPRITE; @@ -13911,7 +14133,7 @@ static void P_SnapperLegPlace(mobj_t *mo) // Move as many legs as available. seg = seg->tracer; - do + while (seg) { o1 = seg->extravalue1; o2 = seg->extravalue2; @@ -13936,7 +14158,7 @@ static void P_SnapperLegPlace(mobj_t *mo) seg->angle = R_PointToAngle2(mo->x, mo->y, seg->x, seg->y); seg = seg->tracer; - } while (seg); + } } // @@ -13960,6 +14182,12 @@ void A_SnapperSpawn(mobj_t *actor) // It spawns 1 head. seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, headtype); + if (P_MobjWasRemoved(seg)) + { + // if we can't spawn the head, don't spawn the snapper at all + P_RemoveMobj(actor); + return; + } P_SetTarget(&ptr->tracer, seg); ptr = seg; @@ -13967,6 +14195,8 @@ void A_SnapperSpawn(mobj_t *actor) for (i = 1; i <= 4; i++) { seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, legtype); + if (P_MobjWasRemoved(seg)) + continue; P_SetTarget(&ptr->tracer, seg); ptr = seg; @@ -14068,7 +14298,8 @@ void A_SnapperThinker(mobj_t *actor) if (actor->reactiontime < 4) { mobj_t *dust = P_SpawnMobj(x0, y0, actor->z, MT_SPINDUST); - P_Thrust(dust, ang + ANGLE_180 + FixedAngle(P_RandomRange(-20, 20)*FRACUNIT), speed*FRACUNIT); + if (!P_MobjWasRemoved(dust)) + P_Thrust(dust, ang + ANGLE_180 + FixedAngle(P_RandomRange(-20, 20)*FRACUNIT), speed*FRACUNIT); } if (actor->extravalue2 == 0) @@ -14178,6 +14409,8 @@ void A_MinecartSparkThink(mobj_t *actor) for (i = 1; i <= 8; i++) { mobj_t *trail = P_SpawnMobj(actor->x - dx*i, actor->y - dy*i, actor->z - dz*i, MT_PARTICLE); + if (P_MobjWasRemoved(trail)) + continue; trail->tics = 2; trail->sprite = actor->sprite; P_SetScale(trail, trail->scale/4); @@ -14263,7 +14496,8 @@ void A_LavafallLava(mobj_t *actor) return; lavafall = P_SpawnMobjFromMobj(actor, 0, 0, -8*FRACUNIT, MT_LAVAFALL_LAVA); - lavafall->momz = -P_MobjFlip(actor)*25*FRACUNIT; + if (!P_MobjWasRemoved(lavafall)) + lavafall->momz = -P_MobjFlip(actor)*25*FRACUNIT; } // Function: A_FallingLavaCheck @@ -14338,9 +14572,18 @@ void A_SpawnPterabytes(mobj_t *actor) c = FINECOSINE(fa); s = FINESINE(fa); waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT); + if (P_MobjWasRemoved(waypoint)) + continue; + waypoint->angle = ang + ANGLE_90; P_SetTarget(&waypoint->tracer, actor); ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE); + if (P_MobjWasRemoved(ptera)) + { + P_RemoveMobj(waypoint); + continue; + } + ptera->angle = waypoint->angle; P_SetTarget(&ptera->tracer, waypoint); ptera->extravalue1 = 0; @@ -14388,14 +14631,17 @@ void A_RolloutSpawn(mobj_t *actor) || P_MobjWasRemoved(actor->target) || P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1) { - actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2); - actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH; - actor->target->eflags |= (actor->eflags & MFE_VERTICALFLIP); - - if (actor->target->flags2 & MF2_AMBUSH) + P_SetTarget(&actor->target, P_SpawnMobj(actor->x, actor->y, actor->z, locvar2)); + if (!P_MobjWasRemoved(actor->target)) { - actor->target->color = SKINCOLOR_SUPERRUST3; - actor->target->colorized = true; + actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH; + actor->target->eflags |= (actor->eflags & MFE_VERTICALFLIP); + + if (actor->target->flags2 & MF2_AMBUSH) + { + actor->target->color = SKINCOLOR_SUPERRUST3; + actor->target->colorized = true; + } } } } @@ -14516,6 +14762,8 @@ void A_DragonbomberSpawn(mobj_t *actor) x = P_ReturnThrustX(mo, mo->angle, -mo->radius << 1); y = P_ReturnThrustY(mo, mo->angle, -mo->radius << 1); segment = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRAGONTAIL); + if (P_MobjWasRemoved(segment)) + continue; P_SetTarget(&segment->target, mo); P_SetTarget(&mo->tracer, segment); segment->angle = mo->angle; @@ -14524,6 +14772,8 @@ void A_DragonbomberSpawn(mobj_t *actor) for (i = 0; i < 2; i++) // spawn wings { mo = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_DRAGONWING); + if (P_MobjWasRemoved(mo)) + continue; P_SetTarget(&mo->target, actor); mo->movedir = ANGLE_90 + i * ANGLE_180; } diff --git a/src/p_floor.c b/src/p_floor.c index 9c24f5851..dcb96a3b2 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1921,6 +1921,9 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) for (c = topz; c > bottomz; c -= spacing) { spawned = P_SpawnMobj(a, b, c, type); + if (P_MobjWasRemoved(spawned)) + continue; + spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones if (fromcenter) diff --git a/src/p_inter.c b/src/p_inter.c index 8bc5c95e4..73d6b707f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -199,6 +199,9 @@ void P_DoNightsScore(player_t *player) player->linktimer = nightslinktics; } + if (P_MobjWasRemoved(dummymo)) + return; + if (player->linkcount < 10) { if (player->bonustime) @@ -1214,7 +1217,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { // A flicky orbits us now mobj_t *flickyobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + toucher->info->height, MT_NIGHTOPIANHELPER); - P_SetTarget(&flickyobj->target, toucher); + if (!P_MobjWasRemoved(flickyobj)) + P_SetTarget(&flickyobj->target, toucher); player->powers[pw_nights_helper] = (UINT16)special->info->speed; } @@ -1225,7 +1229,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) { players[i].powers[pw_nights_helper] = (UINT16)special->info->speed; flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER); - P_SetTarget(&flickyobj->target, players[i].mo); + if (!P_MobjWasRemoved(flickyobj)) + P_SetTarget(&flickyobj->target, players[i].mo); } if (special->info->deathsound != sfx_None) S_StartSound(NULL, special->info->deathsound); @@ -1734,9 +1739,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!player->bot && player->bot != BOT_MPAI && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15))) { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); - P_SetTarget(&mcart->target, toucher); - mcart->angle = toucher->angle = player->drawangle = special->angle; - mcart->friction = FRACUNIT; + if (!P_MobjWasRemoved(mcart)) + { + P_SetTarget(&mcart->target, toucher); + mcart->angle = toucher->angle = player->drawangle = special->angle; + mcart->friction = FRACUNIT; + } P_ResetPlayer(player); player->pflags |= PF_JUMPDOWN; @@ -2506,7 +2514,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget break; } - P_SetMobjState(scoremobj, scorestate); + if (!P_MobjWasRemoved(scoremobj)) + P_SetMobjState(scoremobj, scorestate); source->player->scoreadd = locscoreadd; } @@ -2667,6 +2676,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE); else mo = P_SpawnMobj(target->x, target->y, target->z, MT_EXTRALARGEBUBBLE); + if (P_MobjWasRemoved(mo)) + break; mo->destscale = target->scale; P_SetScale(mo, mo->destscale); P_SetMobjState(mo, mo->info->raisestate); @@ -2745,8 +2756,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mo->angle = FixedAngle((P_RandomKey(36)*10)<angle = mo->angle; - P_SetMobjState(mo2, S_BOSSSEBH2); + if (!P_MobjWasRemoved(mo2)) + { + mo2->angle = mo->angle; + P_SetMobjState(mo2, S_BOSSSEBH2); + } if (++i == 2) // we've already removed 2 of these, let's stop now break; @@ -2845,7 +2859,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (flip) momz *= -1; #define makechunk(angtweak, xmov, ymov) \ + do {\ chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\ + if (P_MobjWasRemoved(chunk))\ + break;\ P_SetMobjState(chunk, target->info->xdeathstate);\ chunk->health = 0;\ chunk->angle = angtweak;\ @@ -2855,7 +2872,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget chunk->y += ymov;\ P_SetThingPosition(chunk);\ P_InstaThrust(chunk,chunk->angle, 4*scale);\ - chunk->momz = momz + chunk->momz = momz;\ + } while (0) makechunk(ang + ANGLE_180, -xoffs, -yoffs); makechunk(ang, xoffs, yoffs); @@ -2868,20 +2886,23 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget momz *= -1; chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE); - P_SetMobjState(chunk, target->info->deathstate); - chunk->health = 0; - chunk->angle = ang + ANGLE_180; - P_UnsetThingPosition(chunk); - chunk->flags = MF_NOCLIP; - chunk->x -= xoffs; - chunk->y -= yoffs; - if (flip) - chunk->z -= 12*scale; - else - chunk->z += 12*scale; - P_SetThingPosition(chunk); - P_InstaThrust(chunk, chunk->angle, 2*scale); - chunk->momz = momz; + if (!P_MobjWasRemoved(chunk)) + { + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = ang + ANGLE_180; + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x -= xoffs; + chunk->y -= yoffs; + if (flip) + chunk->z -= 12*scale; + else + chunk->z += 12*scale; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, chunk->angle, 2*scale); + chunk->momz = momz; + } P_SetMobjState(target, target->info->deathstate); target->health = 0; @@ -2890,7 +2911,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags = MF_NOCLIP; target->x += xoffs; target->y += yoffs; - target->z = chunk->z; + if (flip) + target->z -= 12*scale; + else + target->z += 12*scale; P_SetThingPosition(target); P_InstaThrust(target, target->angle, 2*scale); target->momz = momz; @@ -2913,21 +2937,25 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget sprflip = P_RandomChance(FRACUNIT/2); #define makechunk(angtweak, xmov, ymov) \ - chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\ - P_SetMobjState(chunk, target->info->xdeathstate);\ - chunk->health = 0;\ - chunk->angle = target->angle;\ - P_UnsetThingPosition(chunk);\ - chunk->flags = MF_NOCLIP;\ - chunk->x += xmov - forwardxoffs;\ - chunk->y += ymov - forwardyoffs;\ - P_SetThingPosition(chunk);\ - P_InstaThrust(chunk, angtweak, 4*scale);\ - chunk->momz = P_RandomRange(5, 7)*scale;\ - if (flip)\ - chunk->momz *= -1;\ - if (sprflip)\ - chunk->frame |= FF_VERTICALFLIP + do {\ + chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\ + if (P_MobjWasRemoved(chunk))\ + break;\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = target->angle;\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov - forwardxoffs;\ + chunk->y += ymov - forwardyoffs;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk, angtweak, 4*scale);\ + chunk->momz = P_RandomRange(5, 7)*scale;\ + if (flip)\ + chunk->momz *= -1;\ + if (sprflip)\ + chunk->frame |= FF_VERTICALFLIP;\ + } while (0) makechunk(ang + ANGLE_180, -xoffs, -yoffs); sprflip = !sprflip; @@ -2939,21 +2967,23 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget sprflip = P_RandomChance(FRACUNIT/2); chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE); - - P_SetMobjState(chunk, target->info->deathstate); - chunk->health = 0; - chunk->angle = target->angle; - P_UnsetThingPosition(chunk); - chunk->flags = MF_NOCLIP; - chunk->x += forwardxoffs - xoffs; - chunk->y += forwardyoffs - yoffs; - P_SetThingPosition(chunk); - P_InstaThrust(chunk, ang + ANGLE_180, 2*scale); - chunk->momz = P_RandomRange(5, 7)*scale; - if (flip) - chunk->momz *= -1; - if (sprflip) - chunk->frame |= FF_VERTICALFLIP; + if (!P_MobjWasRemoved(chunk)) + { + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = target->angle; + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x += forwardxoffs - xoffs; + chunk->y += forwardyoffs - yoffs; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, ang + ANGLE_180, 2*scale); + chunk->momz = P_RandomRange(5, 7)*scale; + if (flip) + chunk->momz *= -1; + if (sprflip) + chunk->frame |= FF_VERTICALFLIP; + } P_SetMobjState(target, target->info->deathstate); target->health = 0; @@ -3829,6 +3859,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) z += player->mo->height - mobjinfo[objType].height; mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType); + if (P_MobjWasRemoved(mo)) + continue; mo->fuse = 8*TICRATE; P_SetTarget(&mo->target, player->mo); @@ -3962,6 +3994,9 @@ void P_PlayerWeaponPanelBurst(player_t *player) z += player->mo->height - mobjinfo[weptype].height; mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype); + if (P_MobjWasRemoved(mo)) + continue; + mo->reactiontime = ammoamt; mo->flags2 |= MF2_DONTRESPAWN; mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); @@ -3995,13 +4030,13 @@ void P_PlayerWeaponAmmoBurst(player_t *player) mobj_t *mo; angle_t fa; fixed_t ns; - INT32 i = 0; + INT32 i; fixed_t z; mobjtype_t weptype = 0; powertype_t power = 0; - while (true) + for (i = 0;; i++) { if (player->powers[pw_bouncering]) { @@ -4046,6 +4081,8 @@ void P_PlayerWeaponAmmoBurst(player_t *player) z += player->mo->height - mobjinfo[weptype].height; mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype); + if (P_MobjWasRemoved(mo)) + continue; mo->health = player->powers[power]; mo->flags2 |= MF2_DONTRESPAWN; mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); @@ -4071,8 +4108,6 @@ void P_PlayerWeaponAmmoBurst(player_t *player) if (i & 1) P_SetObjectMomZ(mo, 3*FRACUNIT, true); - - i++; } } @@ -4097,45 +4132,50 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) player->ringweapons &= ~rwflag; \ SETUP_DROP(pickup) \ mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \ - mo->reactiontime = 0; \ - mo->flags2 |= MF2_DONTRESPAWN; \ - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ - P_SetTarget(&mo->target, player->mo); \ - mo->fuse = 12*TICRATE; \ - mo->destscale = player->mo->scale; \ - P_SetScale(mo, player->mo->scale); \ - mo->momx = FixedMul(FINECOSINE(fa),ns); \ - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ - mo->momy = FixedMul(FINESINE(fa),ns); \ - P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ - if (i & 1) \ - P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ - if (player->mo->eflags & MFE_VERTICALFLIP) \ - mo->flags2 |= MF2_OBJECTFLIP; \ - ++i; \ + if (!P_MobjWasRemoved(mo)) \ + { \ + mo->reactiontime = 0; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + mo->flags2 |= MF2_OBJECTFLIP; \ + } \ } \ else if (player->powers[power] > 0) \ { \ SETUP_DROP(ammo) \ mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \ - mo->health = player->powers[power]; \ - mo->flags2 |= MF2_DONTRESPAWN; \ - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ - P_SetTarget(&mo->target, player->mo); \ - mo->fuse = 12*TICRATE; \ - mo->destscale = player->mo->scale; \ - P_SetScale(mo, player->mo->scale); \ - mo->momx = FixedMul(FINECOSINE(fa),ns); \ - if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ - mo->momy = FixedMul(FINESINE(fa),ns); \ - P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ - if (i & 1) \ - P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ - if (player->mo->eflags & MFE_VERTICALFLIP) \ - mo->flags2 |= MF2_OBJECTFLIP; \ - player->powers[power] = 0; \ - ++i; \ - } + if (!P_MobjWasRemoved(mo)) \ + { \ + mo->health = player->powers[power]; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + mo->flags2 |= MF2_OBJECTFLIP; \ + player->powers[power] = 0; \ + } \ + } \ + ++i DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering); DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring); @@ -4259,23 +4299,26 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss) momy = 0; mo = P_SpawnMobj(player->mo->x, player->mo->y, z, MT_FLINGEMERALD); - mo->health = 1; - mo->threshold = stoneflag; - mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH); - mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); - P_SetTarget(&mo->target, player->mo); - mo->fuse = 12*TICRATE; - P_SetMobjState(mo, statenum); - - mo->momx = momx; - mo->momy = momy; - - P_SetObjectMomZ(mo, 3*FRACUNIT, false); - - if (player->mo->eflags & MFE_VERTICALFLIP) + if (!P_MobjWasRemoved(mo)) { - mo->momz = -mo->momz; - mo->flags2 |= MF2_OBJECTFLIP; + mo->health = 1; + mo->threshold = stoneflag; + mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH); + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); + P_SetTarget(&mo->target, player->mo); + mo->fuse = 12*TICRATE; + P_SetMobjState(mo, statenum); + + mo->momx = momx; + mo->momy = momy; + + P_SetObjectMomZ(mo, 3*FRACUNIT, false); + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + mo->momz = -mo->momz; + mo->flags2 |= MF2_OBJECTFLIP; + } } if (toss) @@ -4303,6 +4346,8 @@ void P_PlayerFlagBurst(player_t *player, boolean toss) type = MT_BLUEFLAG; flag = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, type); + if (P_MobjWasRemoved(flag)) + return; if (player->mo->eflags & MFE_VERTICALFLIP) { diff --git a/src/p_local.h b/src/p_local.h index cc060e4ee..b9d07fe24 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -282,7 +282,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype); void P_RespawnSpecials(void); -mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); +mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...); void P_RecalcPrecipInSector(sector_t *sector); void P_PrecipitationEffects(void); diff --git a/src/p_map.c b/src/p_map.c index a7d1f4abd..fc91c8f49 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2861,6 +2861,8 @@ boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) { boolean moveok; mobj_t *hack = P_SpawnMobjFromMobj(thing, 0, 0, 0, MT_RAY); + if (P_MobjWasRemoved(hack)) + return false; hack->radius = thing->radius; hack->height = thing->height; diff --git a/src/p_mobj.c b/src/p_mobj.c index 9e7110de3..920b60272 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -914,29 +914,41 @@ void P_ExplodeMissile(mobj_t *mo) P_RadiusAttack(mo, mo, 96*FRACUNIT, 0, true); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - P_SetScale(explodemo, mo->scale); - explodemo->destscale = mo->destscale; - 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); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + 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_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); - S_StartSound(explodemo, sfx_dmpain); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + 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_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); - S_StartSound(explodemo, sfx_pop); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + 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_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); - S_StartSound(explodemo, sfx_cybdth); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + 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); + } } mo->flags &= ~MF_MISSILE; @@ -3091,6 +3103,8 @@ boolean P_SceneryZMovement(mobj_t *mo) { prandom = P_RandomByte(); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_SMALLBUBBLE); + if (P_MobjWasRemoved(explodemo)) + continue; explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1); explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1); explodemo->destscale = mo->scale; @@ -3362,13 +3376,19 @@ void P_MobjCheckWater(mobj_t *mobj) if (mobj->eflags & MFE_VERTICALFLIP) { splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype); - splish->flags2 |= MF2_OBJECTFLIP; - splish->eflags |= MFE_VERTICALFLIP; + if (!P_MobjWasRemoved(splish)) + { + splish->flags2 |= MF2_OBJECTFLIP; + splish->eflags |= MFE_VERTICALFLIP; + } } else splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); - splish->destscale = mobj->scale; - P_SetScale(splish, mobj->scale); + if (!P_MobjWasRemoved(splish)) + { + splish->destscale = mobj->scale; + P_SetScale(splish, mobj->scale); + } } // skipping stone! @@ -3398,13 +3418,19 @@ void P_MobjCheckWater(mobj_t *mobj) if (mobj->eflags & MFE_VERTICALFLIP) { splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype); - splish->flags2 |= MF2_OBJECTFLIP; - splish->eflags |= MFE_VERTICALFLIP; + if (!P_MobjWasRemoved(splish)) + { + splish->flags2 |= MF2_OBJECTFLIP; + splish->eflags |= MFE_VERTICALFLIP; + } } else splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); - splish->destscale = mobj->scale; - P_SetScale(splish, mobj->scale); + if (!P_MobjWasRemoved(splish)) + { + splish->destscale = mobj->scale; + P_SetScale(splish, mobj->scale); + } } } @@ -4414,11 +4440,14 @@ static void P_Boss3Thinker(mobj_t *mobj) } dummy = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->mass); - dummy->angle = mobj->angle; - dummy->threshold = way1; - P_SetTarget(&dummy->tracer, mobj); - dummy->movefactor = mobj->movefactor; - dummy->cusval = mobj->cusval; + if (!P_MobjWasRemoved(dummy)) + { + dummy->angle = mobj->angle; + dummy->threshold = way1; + P_SetTarget(&dummy->tracer, mobj); + dummy->movefactor = mobj->movefactor; + dummy->cusval = mobj->cusval; + } way2 = P_RandomKey(8-3); if (way2 >= curpath) @@ -4437,11 +4466,14 @@ static void P_Boss3Thinker(mobj_t *mobj) } dummy = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->mass); - dummy->angle = mobj->angle; - dummy->threshold = way2; - P_SetTarget(&dummy->tracer, mobj); - dummy->movefactor = mobj->movefactor; - dummy->cusval = mobj->cusval; + if (!P_MobjWasRemoved(dummy)) + { + dummy->angle = mobj->angle; + dummy->threshold = way2; + P_SetTarget(&dummy->tracer, mobj); + dummy->movefactor = mobj->movefactor; + dummy->cusval = mobj->cusval; + } CONS_Debug(DBG_GAMELOGIC, "Eggman path %d - Dummy selected paths %d and %d\n", way0, way1, way2); if (mobj->spawnpoint) @@ -4559,6 +4591,8 @@ static void P_Boss3Thinker(mobj_t *mobj) for (i = 0; i < numtospawn; i++) { shock = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SHOCKWAVE); + if (P_MobjWasRemoved(shock)) + continue; P_SetTarget(&shock->target, mobj); shock->fuse = shock->info->painchance; @@ -4578,7 +4612,8 @@ static void P_Boss3Thinker(mobj_t *mobj) ang += interval; sprev = shock; } - S_StartSound(mobj, shock->info->seesound); + if (!P_MobjWasRemoved(shock)) + S_StartSound(mobj, shock->info->seesound); // look for a new target P_BossTargetPlayer(mobj, true); @@ -4828,12 +4863,17 @@ static void P_Boss4Thinker(mobj_t *mobj) for (arm = 0; arm <3 ; arm++) { seg = P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE); + if (P_MobjWasRemoved(seg)) + continue; + P_SetTarget(&base->tracer, seg); base = seg; P_SetTarget(&seg->target, mobj); for (i = 0; i < 9; i++) { P_SetTarget(&seg->hnext, P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE)); + if (P_MobjWasRemoved(seg->hnext)) + continue; P_SetTarget(&seg->hnext->hprev, seg); seg = seg->hnext; } @@ -5104,9 +5144,12 @@ static void P_Boss7Thinker(mobj_t *mobj) if (mobj->health >= mobj->info->spawnhealth && (leveltime & 14) == 0) { mobj_t *smoke = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height, MT_SMOKE); - smoke->destscale = mobj->destscale; - P_SetScale(smoke, smoke->destscale); - smoke->momz = FixedMul(FRACUNIT, smoke->scale); + if (!P_MobjWasRemoved(smoke)) + { + smoke->destscale = mobj->destscale; + P_SetScale(smoke, smoke->destscale); + smoke->momz = FixedMul(FRACUNIT, smoke->scale); + } } if (mobj->state == &states[S_BLACKEGG_STND] && mobj->tics == mobj->state->tics) @@ -5380,6 +5423,8 @@ static void P_Boss7Thinker(mobj_t *mobj) y = mobj->y + FixedMul(FINECOSINE(fa),ns); mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + if (P_MobjWasRemoved(mo2)) + continue; ns = 16 * FRACUNIT; mo2->momx = FixedMul(FINESINE(fa),ns); mo2->momy = FixedMul(FINECOSINE(fa),ns); @@ -5573,76 +5618,84 @@ static void P_Boss9Thinker(mobj_t *mobj) mobj_t *missile; missile = P_SpawnMissile(mobj, mobj->target, MT_MSGATHER); - S_StopSound(missile); - if (mobj->extravalue1 >= 2) - P_SetScale(missile, FRACUNIT>>1); - missile->destscale = missile->scale>>1; - missile->fuse = TICRATE/2; - missile->scalespeed = abs(missile->destscale - missile->scale)/missile->fuse; - missile->z -= missile->height/2; - missile->momx *= -1; - missile->momy *= -1; - missile->momz *= -1; + if (!P_MobjWasRemoved(missile)) + { + S_StopSound(missile); + if (mobj->extravalue1 >= 2) + P_SetScale(missile, FRACUNIT>>1); + missile->destscale = missile->scale>>1; + missile->fuse = TICRATE/2; + missile->scalespeed = abs(missile->destscale - missile->scale)/missile->fuse; + missile->z -= missile->height/2; + missile->momx *= -1; + missile->momy *= -1; + missile->momz *= -1; - if (mobj->extravalue1 == 2) - { - UINT8 i; - mobj_t *spread; - for (i = 0; i < 5; i++) + if (mobj->extravalue1 == 2) { - if (i == 2) - continue; - spread = P_SpawnMobj(missile->x, missile->y, missile->z, missile->type); - spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2); - P_InstaThrust(spread,spread->angle,-spread->info->speed); - spread->momz = missile->momz; - P_SetScale(spread, missile->scale); - spread->destscale = missile->destscale; - spread->scalespeed = missile->scalespeed; - spread->fuse = missile->fuse; - P_UnsetThingPosition(spread); - spread->x -= spread->fuse*spread->momx; - spread->y -= spread->fuse*spread->momy; - spread->z -= spread->fuse*spread->momz; - P_SetThingPosition(spread); - } - P_InstaThrust(missile,missile->angle,-missile->info->speed); - } - else if (mobj->extravalue1 >= 3) - { - UINT8 i; - mobj_t *spread; - mobj->target->z -= (4*missile->height); - for (i = 0; i < 5; i++) - { - if (i != 2) + UINT8 i; + mobj_t *spread; + for (i = 0; i < 5; i++) { - spread = P_SpawnMissile(mobj, mobj->target, missile->type); + if (i == 2) + continue; + spread = P_SpawnMobj(missile->x, missile->y, missile->z, missile->type); + if (P_MobjWasRemoved(spread)) + continue; + + spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2); + P_InstaThrust(spread,spread->angle,-spread->info->speed); + spread->momz = missile->momz; P_SetScale(spread, missile->scale); spread->destscale = missile->destscale; + spread->scalespeed = missile->scalespeed; spread->fuse = missile->fuse; - spread->z -= spread->height/2; - spread->momx *= -1; - spread->momy *= -1; - spread->momz *= -1; P_UnsetThingPosition(spread); spread->x -= spread->fuse*spread->momx; spread->y -= spread->fuse*spread->momy; spread->z -= spread->fuse*spread->momz; P_SetThingPosition(spread); } - mobj->target->z += missile->height*2; + P_InstaThrust(missile,missile->angle,-missile->info->speed); } - mobj->target->z -= (6*missile->height); + else if (mobj->extravalue1 >= 3) + { + UINT8 i; + mobj_t *spread; + mobj->target->z -= (4*missile->height); + for (i = 0; i < 5; i++) + { + if (i != 2) + { + spread = P_SpawnMissile(mobj, mobj->target, missile->type); + if (P_MobjWasRemoved(spread)) + continue; + P_SetScale(spread, missile->scale); + spread->destscale = missile->destscale; + spread->fuse = missile->fuse; + spread->z -= spread->height/2; + spread->momx *= -1; + spread->momy *= -1; + spread->momz *= -1; + P_UnsetThingPosition(spread); + spread->x -= spread->fuse*spread->momx; + spread->y -= spread->fuse*spread->momy; + spread->z -= spread->fuse*spread->momz; + P_SetThingPosition(spread); + } + mobj->target->z += missile->height*2; + } + mobj->target->z -= (6*missile->height); + } + + P_UnsetThingPosition(missile); + missile->x -= missile->fuse*missile->momx; + missile->y -= missile->fuse*missile->momy; + missile->z -= missile->fuse*missile->momz; + P_SetThingPosition(missile); + + S_StartSound(mobj, sfx_s3kb3); } - - P_UnsetThingPosition(missile); - missile->x -= missile->fuse*missile->momx; - missile->y -= missile->fuse*missile->momy; - missile->z -= missile->fuse*missile->momz; - P_SetThingPosition(missile); - - S_StartSound(mobj, sfx_s3kb3); } } } @@ -5660,29 +5713,32 @@ static void P_Boss9Thinker(mobj_t *mobj) if (spawner && dist) { mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); - missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); - if (missile->fuse <= 0) // Prevents a division by zero when calculating missile->scalespeed - missile->fuse = 1; + if (!P_MobjWasRemoved(missile)) + { + missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); + if (missile->fuse <= 0) // Prevents a division by zero when calculating missile->scalespeed + missile->fuse = 1; - if (missile->fuse > mobj->fuse) - { - P_RemoveMobj(missile); - } - else - { - if (mobj->health > mobj->info->damage) + if (missile->fuse > mobj->fuse) { - P_SetScale(missile, FRACUNIT/3); - missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power + P_RemoveMobj(missile); } else { - P_SetScale(missile, FRACUNIT/5); - missile->color = SKINCOLOR_SUNSET; // sonic cd electric power + if (mobj->health > mobj->info->damage) + { + P_SetScale(missile, FRACUNIT/3); + missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power + } + else + { + P_SetScale(missile, FRACUNIT/5); + missile->color = SKINCOLOR_SUNSET; // sonic cd electric power + } + missile->destscale = missile->scale*2; + missile->scalespeed = abs(missile->scale - missile->destscale)/missile->fuse; + missile->colorized = true; } - missile->destscale = missile->scale*2; - missile->scalespeed = abs(missile->scale - missile->destscale)/missile->fuse; - missile->colorized = true; } } @@ -5716,6 +5772,7 @@ static void P_Boss9Thinker(mobj_t *mobj) // threshold is used for attacks/maneuvers. if (mobj->threshold && mobj->movecount != 2) { + mobj_t *ghost; fixed_t speed = 20*FRACUNIT + FixedMul(40*FRACUNIT, FixedDiv((mobj->info->spawnhealth - mobj->health)<info->spawnhealth<target, mobj->info->speed); - if (mobj->extravalue1 >= 2) + if (!P_MobjWasRemoved(missile)) { - missile->destscale = FRACUNIT>>1; - P_SetScale(missile, missile->destscale); - } - missile->fuse = 3*TICRATE; - missile->z -= missile->height/2; - - if (mobj->extravalue1 == 2) - { - UINT8 i; - mobj_t *spread; - for (i = 0; i < 5; i++) + if (mobj->extravalue1 >= 2) { - if (i == 2) - continue; - spread = P_SpawnMobj(missile->x, missile->y, missile->z, missile->type); - spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2); - P_InstaThrust(spread,spread->angle,spread->info->speed); - spread->momz = missile->momz; - spread->destscale = FRACUNIT>>1; - P_SetScale(spread, spread->destscale); - spread->fuse = missile->fuse; + missile->destscale = FRACUNIT>>1; + P_SetScale(missile, missile->destscale); } - P_InstaThrust(missile,missile->angle,missile->info->speed); - } - else if (mobj->extravalue1 >= 3) - { - UINT8 i; - mobj_t *spread; - mobj->target->z -= (2*missile->height); - for (i = 0; i < 5; i++) + missile->fuse = 3*TICRATE; + missile->z -= missile->height/2; + + if (mobj->extravalue1 == 2) { - if (i != 2) + UINT8 i; + mobj_t *spread; + for (i = 0; i < 5; i++) { - spread = P_SpawnMissile(mobj, mobj->target, missile->type); + if (i == 2) + continue; + spread = P_SpawnMobj(missile->x, missile->y, missile->z, missile->type); + if (P_MobjWasRemoved(spread)) + continue; + + spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2); + P_InstaThrust(spread,spread->angle,spread->info->speed); + spread->momz = missile->momz; spread->destscale = FRACUNIT>>1; P_SetScale(spread, spread->destscale); spread->fuse = missile->fuse; - spread->z -= spread->height/2; } - mobj->target->z += missile->height; + P_InstaThrust(missile,missile->angle,missile->info->speed); + } + else if (mobj->extravalue1 >= 3) + { + UINT8 i; + mobj_t *spread; + mobj->target->z -= (2*missile->height); + for (i = 0; i < 5; i++) + { + if (i != 2) + { + spread = P_SpawnMissile(mobj, mobj->target, missile->type); + if (!P_MobjWasRemoved(spread)) + { + spread->destscale = FRACUNIT>>1; + P_SetScale(spread, spread->destscale); + spread->fuse = missile->fuse; + spread->z -= spread->height/2; + } + } + mobj->target->z += missile->height; + } + mobj->target->z -= (3*missile->height); } - mobj->target->z -= (3*missile->height); } } else @@ -5837,7 +5903,9 @@ static void P_Boss9Thinker(mobj_t *mobj) return; } - P_SpawnGhostMobj(mobj)->colorized = false; + ghost = P_SpawnGhostMobj(mobj); + if (!P_MobjWasRemoved(ghost)) + ghost->colorized = false; // Vector form dodge! mobj->angle += mobj->movedir; @@ -5935,8 +6003,11 @@ static void P_Boss9Thinker(mobj_t *mobj) if (mobj->health > mobj->info->damage) { // No more bubble if we're broken (pinch phase) mobj_t *shield = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_MSSHIELD_FRONT); - P_SetTarget(&mobj->hprev, shield); - P_SetTarget(&shield->target, mobj); + if (!P_MobjWasRemoved(shield)) + { + P_SetTarget(&mobj->hprev, shield); + P_SetTarget(&shield->target, mobj); + } // Attack 2: Energy shot! switch (mobj->health) @@ -6271,7 +6342,8 @@ void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT finalz = z + v.z; mobj = P_SpawnMobj(finalx, finaly, finalz, type); - mobj->z -= mobj->height/2; + if (!P_MobjWasRemoved(mobj)) + mobj->z -= mobj->height/2; } } @@ -6312,6 +6384,8 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb finalz = z + v.z; mobj = P_SpawnMobj(finalx, finaly, finalz, type); + if (P_MobjWasRemoved(mobj)) + continue; mobj->z -= mobj->height>>1; @@ -6960,6 +7034,8 @@ static void P_KoopaThinker(mobj_t *koopa) { mobj_t *flame; flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_RandomByte()<<(FRACBITS-2)), MT_KOOPAFLAME); + if (P_MobjWasRemoved(flame)) + return; flame->momx = -FixedMul(flame->info->speed, flame->scale); S_StartSound(flame, sfx_koopfr); } @@ -6967,6 +7043,8 @@ static void P_KoopaThinker(mobj_t *koopa) { mobj_t *hammer; hammer = P_SpawnMobj(koopa->x - koopa->radius, koopa->y, koopa->z + koopa->height, MT_HAMMER); + if (P_MobjWasRemoved(hammer)) + return; hammer->momx = FixedMul(-5*FRACUNIT, hammer->scale); hammer->momz = FixedMul(7*FRACUNIT, hammer->scale); } @@ -6985,6 +7063,9 @@ static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode) for (i = 0; i < 4; i++) { seg = P_SpawnMobj(x, y, z, MT_MINECARTSEG); + if (P_MobjWasRemoved(seg)) + continue; + P_SetMobjState(seg, (statenum_t)(S_MINECARTSEG_FRONT + i)); if (i >= 2) seg->extravalue1 = (i == 2) ? -18 : 18; // make -20/20 when papersprite projection fixed @@ -7040,6 +7121,8 @@ static void P_PyreFlyBurn(mobj_t *mobj, fixed_t hoffs, INT16 vrange, mobjtype_t fixed_t yoffs = FixedMul(FINESINE(fa), mobj->radius + hoffs); fixed_t zoffs = P_RandomRange(-vrange, vrange)*FRACUNIT; mobj_t *particle = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, zoffs, mobjtype); + if (P_MobjWasRemoved(particle)) + return; particle->momz = momz; particle->flags2 |= MF2_LINKDRAW; P_SetTarget(&particle->tracer, mobj); @@ -7198,6 +7281,8 @@ static void P_FlameJetSceneryThink(mobj_t *mobj) mobj->fuse -= 2; flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); + if (P_MobjWasRemoved(flame)) + return; P_SetMobjState(flame, S_FLAMEJETFLAME4); flame->angle = mobj->angle; @@ -7236,6 +7321,8 @@ static void P_VerticalFlameJetSceneryThink(mobj_t *mobj) mobj->fuse--; flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); + if (P_MobjWasRemoved(flame)) + return; strength = (mobj->movedir ? mobj->movedir : 80)<<(FRACBITS-2); @@ -7309,13 +7396,16 @@ static boolean P_ParticleGenSceneryThink(mobj_t *mobj) mobj->y + FixedMul(FixedMul(mobj->friction, mobj->scale), FINESINE(mobj->angle >> ANGLETOFINESHIFT)), mobj->z, (mobjtype_t)mobj->threshold); - P_SetScale(spawn, mobj->scale); - spawn->momz = FixedMul(mobj->movefactor, spawn->scale); - spawn->destscale = spawn->scale/100; - spawn->scalespeed = spawn->scale/mobj->health; - spawn->tics = (tic_t)mobj->health; - spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP); - spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones + if (!P_MobjWasRemoved(spawn)) + { + P_SetScale(spawn, mobj->scale); + spawn->momz = FixedMul(mobj->movefactor, spawn->scale); + spawn->destscale = spawn->scale/100; + spawn->scalespeed = spawn->scale/mobj->health; + spawn->tics = (tic_t)mobj->health; + spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP); + spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones + } mobj->angle += mobj->movedir; } @@ -7527,13 +7617,16 @@ static void P_RosySceneryThink(mobj_t *mobj) if (makeheart) { mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT); - cdlhrt->destscale = (5*mobj->scale) >> 4; - P_SetScale(cdlhrt, cdlhrt->destscale); - cdlhrt->fuse = (5*TICRATE) >> 1; - cdlhrt->momz = mobj->scale; - P_SetTarget(&cdlhrt->target, mobj); - cdlhrt->extravalue1 = mobj->x; - cdlhrt->extravalue2 = mobj->y; + if (!P_MobjWasRemoved(cdlhrt)) + { + cdlhrt->destscale = (5*mobj->scale) >> 4; + P_SetScale(cdlhrt, cdlhrt->destscale); + cdlhrt->fuse = (5*TICRATE) >> 1; + cdlhrt->momz = mobj->scale; + P_SetTarget(&cdlhrt->target, mobj); + cdlhrt->extravalue1 = mobj->x; + cdlhrt->extravalue2 = mobj->y; + } } } } @@ -7660,13 +7753,16 @@ static void P_MobjSceneryThink(mobj_t *mobj) && */ (mobj->target->player->pflags & PF_SHIELDABILITY)) { mobj_t *whoosh = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_GHOST); // done here so the offset is correct - P_SetMobjState(whoosh, mobj->info->raisestate); - whoosh->destscale = whoosh->scale << 1; - whoosh->scalespeed = FixedMul(whoosh->scalespeed, whoosh->scale); - whoosh->height = 38*whoosh->scale; - whoosh->fuse = 10; - whoosh->flags |= MF_NOCLIPHEIGHT; - whoosh->momz = mobj->target->momz; // Stay reasonably centered for a few frames + if (!P_MobjWasRemoved(whoosh)) + { + P_SetMobjState(whoosh, mobj->info->raisestate); + whoosh->destscale = whoosh->scale << 1; + whoosh->scalespeed = FixedMul(whoosh->scalespeed, whoosh->scale); + whoosh->height = 38*whoosh->scale; + whoosh->fuse = 10; + whoosh->flags |= MF_NOCLIPHEIGHT; + whoosh->momz = mobj->target->momz; // Stay reasonably centered for a few frames + } mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal whoosh } /* FALLTHRU */ @@ -8007,8 +8103,11 @@ static boolean P_MobjBossThink(mobj_t *mobj) P_RandomRange(rad, -rad) << FRACBITS, P_RandomRange(hei / 2, hei) << FRACBITS, MT_SMOKE); - P_SetObjectMomZ(particle, 2 << FRACBITS, false); - particle->momz += mobj->momz; + if (!P_MobjWasRemoved(particle)) + { + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } } if (mobj->flags2 & MF2_SKULLFLY) #if 1 @@ -8017,8 +8116,11 @@ static boolean P_MobjBossThink(mobj_t *mobj) { mobj_t *spawnmobj; spawnmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->painchance); - P_SetTarget(&spawnmobj->target, mobj); - spawnmobj->color = SKINCOLOR_GREY; + if (!P_MobjWasRemoved(spawnmobj)) + { + P_SetTarget(&spawnmobj->target, mobj); + spawnmobj->color = SKINCOLOR_GREY; + } } #endif P_Boss1Thinker(mobj); @@ -8033,8 +8135,11 @@ static boolean P_MobjBossThink(mobj_t *mobj) P_RandomRange(rad, -rad) << FRACBITS, P_RandomRange(hei/2, hei) << FRACBITS, MT_SMOKE); - P_SetObjectMomZ(particle, 2 << FRACBITS, false); - particle->momz += mobj->momz; + if (!P_MobjWasRemoved(particle)) + { + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } } P_Boss2Thinker(mobj); break; @@ -8048,8 +8153,11 @@ static boolean P_MobjBossThink(mobj_t *mobj) P_RandomRange(rad, -rad) << FRACBITS, P_RandomRange(hei/2, hei) << FRACBITS, MT_SMOKE); - P_SetObjectMomZ(particle, 2 << FRACBITS, false); - particle->momz += mobj->momz; + if (!P_MobjWasRemoved(particle)) + { + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } } P_Boss3Thinker(mobj); break; @@ -8063,8 +8171,11 @@ static boolean P_MobjBossThink(mobj_t *mobj) P_RandomRange(rad, -rad) << FRACBITS, P_RandomRange(hei/2, hei) << FRACBITS, MT_SMOKE); - P_SetObjectMomZ(particle, 2 << FRACBITS, false); - particle->momz += mobj->momz; + if (!P_MobjWasRemoved(particle)) + { + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } } P_Boss4Thinker(mobj); break; @@ -8192,6 +8303,9 @@ static boolean P_MobjDeadThink(mobj_t *mobj) y = mobj->y + FixedMul(FINECOSINE(fa), ns); mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + if (P_MobjWasRemoved(mo2)) + continue; + P_SetMobjStateNF(mo2, S_XPLD_EGGTRAP); // so the flickies don't lose their target if they spawn ns = 4*FRACUNIT; mo2->momx = FixedMul(FINESINE(fa), ns); @@ -8237,7 +8351,8 @@ static boolean P_MobjDeadThink(mobj_t *mobj) mobj->y + (P_RandomRange(r, -r) << FRACBITS), mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), MT_SONIC3KBOSSEXPLODE); - S_StartSound(explosion, sfx_s3kb4); + if (!P_MobjWasRemoved(explosion)) + S_StartSound(explosion, sfx_s3kb4); } if (mobj->movedir == DMG_DROWNED) P_SetObjectMomZ(mobj, -FRACUNIT/2, true); // slower fall from drowning @@ -8255,7 +8370,8 @@ static boolean P_MobjDeadThink(mobj_t *mobj) mobj->y + (P_RandomRange(r, -r) << FRACBITS), mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), MT_SONIC3KBOSSEXPLODE); - S_StartSound(explosion, sfx_s3kb4); + if (!P_MobjWasRemoved(explosion)) + S_StartSound(explosion, sfx_s3kb4); } P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); } @@ -8353,9 +8469,12 @@ static void P_ArrowThink(mobj_t *mobj) if (leveltime & 1) { mobj_t *dust = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_PARTICLE); - dust->tics = 18; - dust->scalespeed = 4096; - dust->destscale = FRACUNIT/32; + if (!P_MobjWasRemoved(dust)) + { + dust->tics = 18; + dust->scalespeed = 4096; + dust->destscale = FRACUNIT/32; + } } } else @@ -8958,6 +9077,9 @@ static boolean P_TurretThink(mobj_t *mobj) y = mobj->y + FixedMul(FINECOSINE(fa), ns); mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + if (P_MobjWasRemoved(mo2)) + continue; + ns = FixedMul(16*FRACUNIT, mobj->scale); mo2->momx = FixedMul(FINESINE(fa), ns); mo2->momy = FixedMul(FINECOSINE(fa), ns); @@ -9179,10 +9301,13 @@ static void P_DragonbomberThink(mobj_t *mobj) if (segment != mobj) // found an unactivated segment? { mobj_t *mine = P_SpawnMobjFromMobj(segment, 0, 0, 0, segment->info->painchance); - mine->angle = segment->angle; - P_InstaThrust(mine, mobj->angle, P_AproxDistance(mobj->momx, mobj->momy) >> 1); - P_SetObjectMomZ(mine, -2*FRACUNIT, true); - S_StartSound(mine, mine->info->seesound); + if (!P_MobjWasRemoved(mine)) + { + mine->angle = segment->angle; + P_InstaThrust(mine, mobj->angle, P_AproxDistance(mobj->momx, mobj->momy) >> 1); + P_SetObjectMomZ(mine, -2*FRACUNIT, true); + S_StartSound(mine, mine->info->seesound); + } P_SetMobjState(segment, segment->info->raisestate); mobj->threshold = mobj->info->painchance; } @@ -9401,9 +9526,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (!mobj->threshold && !mobj->target && mobj->reactiontime) { mobj_t *emerald = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->reactiontime); - emerald->threshold = 42; - P_SetTarget(&mobj->target, emerald); - P_SetTarget(&emerald->target, mobj); + if (!P_MobjWasRemoved(emerald)) + { + emerald->threshold = 42; + P_SetTarget(&mobj->target, emerald); + P_SetTarget(&emerald->target, mobj); + } } } break; @@ -9745,6 +9873,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_TRAINDUSTSPAWNER: if (leveltime % 5 == 0) { mobj_t* traindust = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PARTICLE); + if (P_MobjWasRemoved(traindust)) + break; traindust->flags = MF_SCENERY; P_SetMobjState(traindust, S_TRAINDUST); traindust->frame = P_RandomRange(0, 8)|FF_TRANS90; @@ -9758,6 +9888,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_TRAINSTEAMSPAWNER: if (leveltime % 5 == 0) { mobj_t *steam = P_SpawnMobj(mobj->x + FRACUNIT*P_SignedRandom()/2, mobj->y + FRACUNIT*P_SignedRandom()/2, mobj->z, MT_PARTICLE); + if (P_MobjWasRemoved(steam)) + break; P_SetMobjState(steam, S_TRAINSTEAM); steam->frame = P_RandomRange(0, 1)|FF_TRANS90; steam->tics = TICRATE*8; @@ -9959,7 +10091,8 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); // Transfer flags2 (ambush, strongbox, objectflip) - newmobj->flags2 = mobj->flags2; + if (!P_MobjWasRemoved(newmobj)) + newmobj->flags2 = mobj->flags2; P_RemoveMobj(mobj); // make sure they disappear } @@ -9981,6 +10114,8 @@ static void P_FlagFuseThink(mobj_t *mobj) else z = ss->sector->floorheight + z; flagmo = P_SpawnMobj(x, y, z, mobj->type); + if (P_MobjWasRemoved(flagmo)) + return; flagmo->spawnpoint = mobj->spawnpoint; if (mobj->spawnpoint->options & MTF_OBJECTFLIP) { @@ -10418,12 +10553,15 @@ void P_PushableThinker(mobj_t *mobj) z = ss->sector->floorheight; spawnmo = P_SpawnMobj(x, y, z, mobj->type); - spawnmo->spawnpoint = mobj->spawnpoint; - P_UnsetThingPosition(spawnmo); - spawnmo->flags = mobj->flags; - P_SetThingPosition(spawnmo); - spawnmo->flags2 = mobj->flags2; - spawnmo->flags |= MF_PUSHABLE; + if (!P_MobjWasRemoved(spawnmo)) + { + spawnmo->spawnpoint = mobj->spawnpoint; + P_UnsetThingPosition(spawnmo); + spawnmo->flags = mobj->flags; + P_SetThingPosition(spawnmo); + spawnmo->flags2 = mobj->flags2; + spawnmo->flags |= MF_PUSHABLE; + } P_RemoveMobj(mobj); break; default: @@ -10575,27 +10713,17 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) // // P_SpawnMobj // -mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) +mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) { const mobjinfo_t *info = &mobjinfo[type]; SINT8 sc = -1; state_t *st; mobj_t *mobj; + int status; + va_list args; if (type == MT_NULL) - { -#if 0 -#ifdef PARANOIA - I_Error("Tried to spawn MT_NULL\n"); -#endif return NULL; -#endif - // Hack: Some code assumes that P_SpawnMobj can never return NULL - // So replace MT_NULL with MT_RAY in the meantime - // Remove when dealt properly - CONS_Debug(DBG_GAMELOGIC, "Tried to spawn MT_NULL, using MT_RAY\n"); - type = MT_RAY; - } mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); @@ -10687,9 +10815,27 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // Set shadowscale here, before spawn hook so that Lua can change it mobj->shadowscale = P_DefaultMobjShadowScale(mobj); + if (!(mobj->flags & MF_NOTHINK)) + P_AddThinker(THINK_MOBJ, &mobj->thinker); + + + if (type == MT_PLAYER) + { + // when spawning MT_PLAYER, set mobj->player before calling MobjSpawn hook to prevent P_RemoveMobj from succeeding on player mobj. + va_start(args, type); + mobj->player = va_arg(args, player_t *); + va_end(args); + } + + // increment mobj reference, so we don't get a dangling reference in case MobjSpawn calls P_RemoveMobj + mobj->thinker.references++; + // DANGER! This can cause P_SpawnMobj to return NULL! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! - if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjSpawn))) + status = LUA_HookMobj(mobj, MOBJ_HOOK(MobjSpawn)); + mobj->thinker.references--; + + if (status) { if (P_MobjWasRemoved(mobj)) return NULL; @@ -10711,6 +10857,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BLACKEGGMAN: { mobj_t *spawn = P_SpawnMobj(mobj->x, mobj->z, mobj->z+mobj->height-16*FRACUNIT, MT_BLACKEGGMAN_HELPER); + if (P_MobjWasRemoved(spawn)) + break; + spawn->destscale = mobj->scale; P_SetScale(spawn, mobj->scale); P_SetTarget(&spawn->target, mobj); @@ -10726,6 +10875,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_EGGGUARD: { mobj_t *spawn = P_SpawnMobj(x, y, z, MT_EGGSHIELD); + if (P_MobjWasRemoved(spawn)) + break; + spawn->destscale = mobj->scale; P_SetScale(spawn, mobj->scale); P_SetTarget(&mobj->tracer, spawn); @@ -10741,6 +10893,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) for (i = 0; i < mobj->info->damage; i++) { ball = P_SpawnMobj(x, y, z, mobj->info->painchance); + if (P_MobjWasRemoved(ball)) + continue; + ball->destscale = mobj->scale; P_SetScale(ball, mobj->scale); P_SetTarget(&ball->target, mobj); @@ -10760,6 +10915,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) for (q = 0; q < mobj->info->painchance; q++) { ball = P_SpawnMobj(x, y, z, mobj->info->mass); + if (P_MobjWasRemoved(ball)) + continue; + ball->destscale = mobj->scale; P_SetScale(ball, mobj->scale); P_SetTarget(&lastball->tracer, ball); @@ -10771,18 +10929,24 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_CRUSHSTACEAN: { mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CRUSHCLAW); - bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);; - P_SetTarget(&mobj->tracer, bigmeatyclaw); - P_SetTarget(&bigmeatyclaw->tracer, mobj); + if (!P_MobjWasRemoved(bigmeatyclaw)) + { + bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); + P_SetTarget(&mobj->tracer, bigmeatyclaw); + P_SetTarget(&bigmeatyclaw->tracer, mobj); + } mobj->reactiontime >>= 1; } break; case MT_BANPYURA: { mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING); - bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);; - P_SetTarget(&mobj->tracer, bigmeatyclaw); - P_SetTarget(&bigmeatyclaw->tracer, mobj); + if (!P_MobjWasRemoved(bigmeatyclaw)) + { + bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); + P_SetTarget(&mobj->tracer, bigmeatyclaw); + P_SetTarget(&bigmeatyclaw->tracer, mobj); + } mobj->reactiontime >>= 1; } break; @@ -10797,6 +10961,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) for (i = 0; i <= 16; i++) // probably should be < but staying authentic to the Lua version { cur = P_SpawnMobjFromMobj(mobj, 0, 0, 0, ((mobj->type == MT_WAVINGFLAG1) ? MT_WAVINGFLAGSEG1 : MT_WAVINGFLAGSEG2));; + if (P_MobjWasRemoved(cur)) + continue; + P_SetTarget(&prev->tracer, cur); cur->extravalue1 = i; prev = cur; @@ -10834,11 +11001,17 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { mobj_t *fire; fire = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SPINBOBERT_FIRE1); - P_SetTarget(&fire->target, mobj); - P_SetTarget(&mobj->hnext, fire); + if (!P_MobjWasRemoved(fire)) + { + P_SetTarget(&fire->target, mobj); + P_SetTarget(&mobj->hnext, fire); + } fire = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SPINBOBERT_FIRE2); - P_SetTarget(&fire->target, mobj); - P_SetTarget(&mobj->hprev, fire); + if (!P_MobjWasRemoved(fire)) + { + P_SetTarget(&fire->target, mobj); + P_SetTarget(&mobj->hprev, fire); + } } break; case MT_REDRING: // Make MT_REDRING red by default @@ -10855,8 +11028,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_EGGCAPSULE: mobj->reactiontime = 0; mobj->extravalue1 = mobj->cvmem =\ - mobj->cusval = mobj->movecount =\ - mobj->lastlook = mobj->extravalue2 = -1; + mobj->cusval = mobj->movecount =\ + mobj->lastlook = mobj->extravalue2 = -1; break; case MT_REDTEAMRING: mobj->color = skincolor_redteam; @@ -10892,6 +11065,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_OILLAMP: { mobj_t* overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + if (P_MobjWasRemoved(overlay)) + break; P_SetTarget(&overlay->target, mobj); P_SetMobjState(overlay, S_OILLAMPFLARE); break; @@ -10901,13 +11076,19 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->flags2 |= MF2_INVERTAIMABLE; break; case MT_MINECARTEND: - P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID)); - mobj->tracer->angle = mobj->angle + ANGLE_90; + { + mobj_t *mcsolid = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID); + if (P_MobjWasRemoved(mcsolid)) + break; + P_SetTarget(&mobj->tracer, mcsolid); + mcsolid->angle = mobj->angle + ANGLE_90; + } break; case MT_TORCHFLOWER: { mobj_t *fire = P_SpawnMobjFromMobj(mobj, 0, 0, 46*FRACUNIT, MT_FLAME); - P_SetTarget(&mobj->target, fire); + if (!P_MobjWasRemoved(fire)) + P_SetTarget(&mobj->target, fire); break; } case MT_PYREFLY: @@ -10916,10 +11097,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->fuse = 100; break; case MT_SIGN: - P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY)); - P_SetTarget(&mobj->tracer->target, mobj); - P_SetMobjState(mobj->tracer, S_SIGNBOARD); - mobj->tracer->movedir = ANGLE_90; + { + mobj_t *sign = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY); + if (P_MobjWasRemoved(sign)) + break; + + P_SetTarget(&mobj->tracer, sign); + P_SetTarget(&sign->target, mobj); + P_SetMobjState(sign, S_SIGNBOARD); + sign->movedir = ANGLE_90; + } default: break; } @@ -10942,9 +11129,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) } } - if (!(mobj->flags & MF_NOTHINK)) - P_AddThinker(THINK_MOBJ, &mobj->thinker); - if (mobj->skin) // correct inadequecies above. { mobj->sprite2 = P_GetSkinSprite2(mobj->skin, (mobj->frame & FF_FRAMEMASK), NULL); @@ -11553,8 +11737,10 @@ void P_SpawnPlayer(INT32 playernum) if ((netgame || multiplayer) && ((gametyperules & GTR_SPAWNINVUL) || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS)) p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent - mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); - (mobj->player = p)->mo = mobj; + // MT_PLAYER cannot be removed, so this shouldn't be able to return NULL. + mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER, p); + I_Assert(mobj != NULL); + p->mo = mobj; mobj->angle = 0; @@ -11605,10 +11791,13 @@ void P_SpawnPlayer(INT32 playernum) if (p == players) // this is totally the wrong place to do this aaargh. { mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD); - idya->health = 0; // for identification - P_SetTarget(&idya->target, mobj); - P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); - P_SetTarget(&mobj->tracer, idya); + if (!P_MobjWasRemoved(idya)) + { + idya->health = 0; // for identification + P_SetTarget(&idya->target, mobj); + P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); + P_SetTarget(&mobj->tracer, idya); + } } } else if (sstimer) @@ -12357,8 +12546,10 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) mphase = (FixedAngle(mphase << FRACBITS) >> ANGLETOFINESHIFT); mroll = (FixedAngle(mroll << FRACBITS) >> ANGLETOFINESHIFT); -#define makemace(mobjtype, dist, moreflags2) {\ +#define makemace(mobjtype, dist, moreflags2) do {\ spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ + if (P_MobjWasRemoved(spawnee))\ + break;\ P_SetTarget(&spawnee->tracer, mobj);\ spawnee->threshold = mphase;\ spawnee->friction = mroll;\ @@ -12371,7 +12562,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) P_SetTarget(&hprev->hnext, spawnee);\ P_SetTarget(&spawnee->hprev, hprev);\ hprev = spawnee;\ -} +} while (0) mdosound = (mspeed && !(mthing->args[8] & TMM_SILENT)); mdocenter = (macetype && (mthing->args[8] & TMM_CENTERLINK)); @@ -12436,7 +12627,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) if (!mwidth) { - if (mdosound && mnumspokes <= mmin) // Can it make a sound? + if (!P_MobjWasRemoved(spawnee) && mdosound && mnumspokes <= mmin) // Can it make a sound? spawnee->flags2 |= MF2_BOSSNOTRAP; } else @@ -12449,7 +12640,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) while ((mwidthset -= widthfactor) > -mwidth) { makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + if (!P_MobjWasRemoved(spawnee) && mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? spawnee->flags2 |= MF2_BOSSNOTRAP; } } @@ -12458,7 +12649,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) while ((mwidthset += widthfactor) < -mwidth) { makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + if (!P_MobjWasRemoved(spawnee) && mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? spawnee->flags2 |= MF2_BOSSNOTRAP; } } @@ -12640,15 +12831,21 @@ static boolean P_SetupNiGHTSDrone(mapthing_t *mthing, mobj_t *mobj) mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, dronemanoffset, MT_NIGHTSDRONE_MAN); P_SetTarget(&mobj->target, goalpost); - P_SetTarget(&goalpost->target, sparkle); - P_SetTarget(&goalpost->tracer, droneman); + if (!P_MobjWasRemoved(goalpost)) + { + P_SetTarget(&goalpost->target, sparkle); + P_SetTarget(&goalpost->tracer, droneman); + } // correct Z position if (flip) { - P_MoveOrigin(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset); - P_MoveOrigin(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset); - P_MoveOrigin(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset); + if (!P_MobjWasRemoved(goalpost)) + P_MoveOrigin(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset); + if (!P_MobjWasRemoved(sparkle)) + P_MoveOrigin(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset); + if (!P_MobjWasRemoved(droneman)) + P_MoveOrigin(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset); } // Remember position preference for later @@ -12670,9 +12867,12 @@ static boolean P_SetupNiGHTSDrone(mapthing_t *mthing, mobj_t *mobj) } // Remember old Z position and flags for correction detection - goalpost->movefactor = mobj->z; - goalpost->friction = mobj->height; - goalpost->threshold = mobj->flags & (MF_SLIDEME|MF_GRENADEBOUNCE); + if (!P_MobjWasRemoved(goalpost)) + { + goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; + goalpost->threshold = mobj->flags & (MF_SLIDEME|MF_GRENADEBOUNCE); + } } return true; } @@ -12690,30 +12890,54 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong) statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER; mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle - ANGLE_90; - P_SetMobjState(seg, facestate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle - ANGLE_90; + P_SetMobjState(seg, facestate); + } seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle + ANGLE_90; - P_SetMobjState(seg, facestate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle + ANGLE_90; + P_SetMobjState(seg, facestate); + } seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, leftstate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle; + P_SetMobjState(seg, leftstate); + } seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, rightstate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle; + P_SetMobjState(seg, rightstate); + } seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + } seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + } seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + } seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); + if (!P_MobjWasRemoved(seg)) + { + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + } return true; } @@ -12721,6 +12945,9 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong) static mobj_t *P_MakeSoftwareCorona(mobj_t *mo, INT32 height) { mobj_t *corona = P_SpawnMobjFromMobj(mo, 0, 0, height<sprite = SPR_FLAM; corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12); corona->tics = -1; @@ -12856,6 +13083,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (mthing->args[0]) { mobj_t *corona = P_MakeSoftwareCorona(mobj, 20); + if (P_MobjWasRemoved(corona)) + break; + P_SetScale(corona, (corona->destscale = mobj->scale*3)); P_SetTarget(&mobj->tracer, corona); } @@ -12864,11 +13094,17 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (!(mthing->args[0] & TMFH_NOFLAME)) // Spawn the fire { mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME); + if (P_MobjWasRemoved(flame)) + break; + P_SetTarget(&flame->target, mobj); flame->flags2 |= MF2_BOSSNOTRAP; if (mthing->args[0] & TMFH_CORONA) { mobj_t *corona = P_MakeSoftwareCorona(flame, 20); + if (P_MobjWasRemoved(corona)) + break; + P_SetScale(corona, (corona->destscale = flame->scale*3)); P_SetTarget(&flame->tracer, corona); } @@ -12885,6 +13121,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (!(mthing->args[0])) // take the torch out of the crafting recipe { mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY); + if (P_MobjWasRemoved(overlay)) + break; P_SetTarget(&overlay->target, mobj); P_SetMobjState(overlay, mobj->info->raisestate); } @@ -12964,9 +13202,15 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_THZTREE: { // Spawn the branches angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS); - P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h; - P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h; - P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; + mobj_t *branch = P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH); + if (!P_MobjWasRemoved(branch)) + branch->angle = mobjangle + ANGLE_22h; + branch = P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH); + if (!P_MobjWasRemoved(branch)) + branch->angle = mobjangle + ANGLE_157h; + branch = P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH); + if (!P_MobjWasRemoved(branch)) + branch->angle = mobjangle + ANGLE_270; } break; case MT_TUTORIALPLANT: @@ -12976,26 +13220,34 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean for (i = 0; i < 6; i++) { segment = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_TUTORIALLEAF); + if (P_MobjWasRemoved(segment)) + continue; segment->angle = mobj->angle + FixedAngle(i*60*FRACUNIT); P_SetMobjState(segment, S_TUTORIALLEAF1 + mthing->args[0]); } for (i = 0; i < 3; i++) { segment = P_SpawnMobjFromMobj(mobj, 0, 0, 112*FRACUNIT, MT_TUTORIALFLOWER); + if (P_MobjWasRemoved(segment)) + continue; segment->angle = mobj->angle + FixedAngle(i*120*FRACUNIT); P_SetMobjState(segment, S_TUTORIALFLOWER1 + mthing->args[0]); } - P_SetMobjState(P_SpawnMobjFromMobj(mobj, 0, 0, 112*FRACUNIT, MT_TUTORIALFLOWERF), S_TUTORIALFLOWERF1 + mthing->args[0]); + segment = P_SpawnMobjFromMobj(mobj, 0, 0, 112*FRACUNIT, MT_TUTORIALFLOWERF); + if (!P_MobjWasRemoved(segment)) + P_SetMobjState(segment, S_TUTORIALFLOWERF1 + mthing->args[0]); } break; case MT_CEZPOLE1: case MT_CEZPOLE2: { // Spawn the banner angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); - P_SpawnMobjFromMobj(mobj, + mobj_t *banner = P_SpawnMobjFromMobj(mobj, P_ReturnThrustX(mobj, mobjangle, 4 << FRACBITS), P_ReturnThrustY(mobj, mobjangle, 4 << FRACBITS), - 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90; + 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2)); + if (!P_MobjWasRemoved(banner)) + banner->angle = mobjangle + ANGLE_90; } break; case MT_HHZTREE_TOP: @@ -13004,8 +13256,11 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj_t* leaf; #define doleaf(x, y) \ leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\ - leaf->angle = mobjangle;\ - P_SetMobjState(leaf, leaf->info->seestate);\ + if (!P_MobjWasRemoved(leaf))\ + {\ + leaf->angle = mobjangle;\ + P_SetMobjState(leaf, leaf->info->seestate);\ + }\ mobjangle += ANGLE_90 doleaf(FRACUNIT, 0); doleaf(0, FRACUNIT); @@ -13044,8 +13299,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; fixed_t xoffs = FINECOSINE(fa); fixed_t yoffs = FINESINE(fa); - mobj_t* leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF); - leaf->angle = angle; + mobj_t *leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF); + if (!P_MobjWasRemoved(leaf)) + leaf->angle = angle; angle += ANGLE_45; } break; @@ -13082,6 +13338,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean { mobj_t* elecmobj; elecmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_CYBRAKDEMON_ELECTRIC_BARRIER); + if (P_MobjWasRemoved(elecmobj)) + break; P_SetTarget(&elecmobj->target, mobj); elecmobj->angle = FixedAngle(mthing->angle << FRACBITS); elecmobj->destscale = mobj->scale*2; @@ -13136,6 +13394,12 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), mobj->z, MT_WALLSPIKEBASE); + if (P_MobjWasRemoved(base)) + { + // if we can't spawn the base, don't spawn the spike at all. + P_RemoveMobj(mobj); + return false; + } base->angle = mobjangle + ANGLE_90; base->destscale = mobj->destscale; P_SetScale(base, mobj->scale); @@ -13311,6 +13575,8 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, boolean doangle = true; mobj = P_SpawnMobj(x, y, z, i); + if (mobj == NULL) + return NULL; mobj->spawnpoint = mthing; P_SetScale(mobj, FixedMul(mobj->scale, mthing->scale)); @@ -13405,6 +13671,9 @@ void P_SpawnHoop(mapthing_t *mthing) fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); + if (P_MobjWasRemoved(hoopcenter)) + return; + hoopcenter->spawnpoint = mthing; hoopcenter->z -= hoopcenter->height/2; @@ -13435,6 +13704,8 @@ void P_SpawnHoop(mapthing_t *mthing) FV4_Copy(&v, FM_MultMatrixVec4(&yawmatrix, &v, &res)); mobj = P_SpawnMobj(x + v.x, y + v.y, z + v.z, MT_HOOP); + if (P_MobjWasRemoved(mobj)) + continue; mobj->z -= mobj->height/2; if (maptol & TOL_XMAS) @@ -13479,6 +13750,8 @@ void P_SpawnHoop(mapthing_t *mthing) FV4_Copy(&v, FM_MultMatrixVec4(&yawmatrix, &v, &res)); mobj = P_SpawnMobj(x + v.x, y + v.y, z + v.z, MT_HOOPCOLLIDE); + if (P_MobjWasRemoved(mobj)) + continue; mobj->z -= mobj->height/2; // Link all the collision sprites together. @@ -13752,6 +14025,8 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, z -= FixedMul(mobjinfo[type].height, source->scale); th = P_SpawnMobj(x, y, z, type); + if (P_MobjWasRemoved(th)) + return NULL; if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; @@ -13814,6 +14089,8 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t z -= FixedMul(mobjinfo[type].height, source->scale); th = P_SpawnMobj(x, y, z, type); + if (P_MobjWasRemoved(th)) + return NULL; if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; @@ -13879,6 +14156,8 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, z -= FixedMul(mobjinfo[type].height, source->scale); th = P_SpawnMobj(x, y, z, type); + if (P_MobjWasRemoved(th)) + return NULL; if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; @@ -13949,6 +14228,8 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type) z -= FixedMul(mobjinfo[type].height, source->scale); th = P_SpawnMobj(source->x, source->y, z, type); + if (P_MobjWasRemoved(th)) + return NULL; if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; @@ -14050,6 +14331,8 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai z = source->z + source->height/3; th = P_SpawnMobj(x, y, z, type); + if (P_MobjWasRemoved(th)) + return NULL; if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; diff --git a/src/p_polyobj.c b/src/p_polyobj.c index b207bb740..331bc5c7f 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1243,6 +1243,8 @@ boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolea // Returns NULL if no such polyobject exists. polyobj_t *Polyobj_GetForNum(INT32 id) { + if (numPolyObjects == 0) + return NULL; INT32 curidx = PolyObjects[id % numPolyObjects].first; while (curidx != numPolyObjects && PolyObjects[curidx].id != id) diff --git a/src/p_user.c b/src/p_user.c index d441a7e81..658a35711 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -394,6 +394,8 @@ void P_GiveFinishFlags(player_t *player) fixed_t xoffs = FINECOSINE(fa); fixed_t yoffs = FINESINE(fa); mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG); + if (P_MobjWasRemoved(flag)) + continue; flag->angle = angle; angle += FixedAngle(120*FRACUNIT); @@ -1826,6 +1828,9 @@ void P_SpawnShieldOrb(player_t *player) } shieldobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, orbtype); + if (P_MobjWasRemoved(shieldobj)) + return; + shieldobj->flags2 |= MF2_SHIELD; P_SetTarget(&shieldobj->target, player->mo); if ((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) @@ -1840,21 +1845,30 @@ void P_SpawnShieldOrb(player_t *player) if (shieldobj->info->seestate) { ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); - P_SetTarget(&ov->target, shieldobj); - P_SetMobjState(ov, shieldobj->info->seestate); - P_SetTarget(&shieldobj->tracer, ov); + if (!P_MobjWasRemoved(ov)) + { + P_SetTarget(&ov->target, shieldobj); + P_SetMobjState(ov, shieldobj->info->seestate); + P_SetTarget(&shieldobj->tracer, ov); + } } if (shieldobj->info->meleestate) { ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); - P_SetTarget(&ov->target, shieldobj); - P_SetMobjState(ov, shieldobj->info->meleestate); + if (!P_MobjWasRemoved(ov)) + { + P_SetTarget(&ov->target, shieldobj); + P_SetMobjState(ov, shieldobj->info->meleestate); + } } if (shieldobj->info->missilestate) { ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); - P_SetTarget(&ov->target, shieldobj); - P_SetMobjState(ov, shieldobj->info->missilestate); + if (!P_MobjWasRemoved(ov)) + { + P_SetTarget(&ov->target, shieldobj); + P_SetMobjState(ov, shieldobj->info->missilestate); + } } if (player->powers[pw_shield] & SH_FORCE) { @@ -1950,6 +1964,8 @@ void P_SetPower(player_t *player, powertype_t power, UINT16 value) mobj_t *P_SpawnGhostMobj(mobj_t *mobj) { mobj_t *ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST); + if (P_MobjWasRemoved(ghost)) + return NULL; P_SetTarget(&ghost->target, mobj); @@ -1992,9 +2008,12 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) if (mobj->player && mobj->player->followmobj) { mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj); - P_SetTarget(&ghost2->tracer, ghost); - P_SetTarget(&ghost->tracer, ghost2); - ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); + if (!P_MobjWasRemoved(ghost2)) + { + P_SetTarget(&ghost2->tracer, ghost); + P_SetTarget(&ghost->tracer, ghost2); + ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); + } } // Copy interpolation data :) @@ -2043,6 +2062,8 @@ void P_SpawnThokMobj(player_t *player) zheight = player->mo->ceilingz - FixedMul(mobjinfo[type].height, player->mo->scale); mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type); + if (P_MobjWasRemoved(mobj)) + return; // set to player's angle, just in case mobj->angle = player->drawangle; @@ -2066,7 +2087,8 @@ void P_SpawnThokMobj(player_t *player) } } - P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do + if (!P_MobjWasRemoved(mobj)) + P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do G_GhostAddThok(); } @@ -2104,6 +2126,8 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type) zheight = player->mo->ceilingz - FixedMul(mobjinfo[type].height, player->mo->scale); mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type); + if (P_MobjWasRemoved(mobj)) + return; // set to player's angle, just in case mobj->angle = player->drawangle; @@ -2128,7 +2152,8 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type) } } - P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do + if (!P_MobjWasRemoved(mobj)) + P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do } /** Called when \p player finishes the level. @@ -2352,15 +2377,18 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) while (i < 5) { missile = P_SpawnMobjFromMobj(player->mo, xo, yo, zo, type); - P_SetTarget(&missile->target, player->mo); - missile->angle = throwang + player->drawangle; - P_Thrust(missile, player->drawangle + ANGLE_90, - P_ReturnThrustY(missile, throwang, mu)); // side to side component - P_Thrust(missile, player->drawangle, mu2); // forward component - P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true); - missile->momz += player->mo->pmomz; - missile->fuse = TICRATE/2; - missile->extravalue2 = ev; + if (!P_MobjWasRemoved(missile)) + { + P_SetTarget(&missile->target, player->mo); + missile->angle = throwang + player->drawangle; + P_Thrust(missile, player->drawangle + ANGLE_90, + P_ReturnThrustY(missile, throwang, mu)); // side to side component + P_Thrust(missile, player->drawangle, mu2); // forward component + P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true); + missile->momz += player->mo->pmomz; + missile->fuse = TICRATE/2; + missile->extravalue2 = ev; + } i++; throwang += ANG30; @@ -2912,24 +2940,29 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) : player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, FixedMul(player->mo->scale, player->shieldscale)); mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - - timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us - - if (player->charflags & SF_MACHINE) + if (!P_MobjWasRemoved(numbermobj)) { - S_StartSound(player->mo, sfx_buzz1); - timeleft += 6; + timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us + + if (player->charflags & SF_MACHINE) + { + S_StartSound(player->mo, sfx_buzz1); + timeleft += 6; + } + else + S_StartSound(player->mo, sfx_dwnind); + + if (!P_MobjWasRemoved(numbermobj)) + { + if (timeleft) // Don't waste time setting the state if the time is 0. + P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft); + + P_SetTarget(&numbermobj->target, player->mo); + numbermobj->threshold = 40; + numbermobj->destscale = player->mo->scale; + P_SetScale(numbermobj, player->mo->scale); + } } - else - S_StartSound(player->mo, sfx_dwnind); - - if (timeleft) // Don't waste time setting the state if the time is 0. - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft); - - P_SetTarget(&numbermobj->target, player->mo); - numbermobj->threshold = 40; - numbermobj->destscale = player->mo->scale; - P_SetScale(numbermobj, player->mo->scale); } // Underwater timer runs out else if (timeleft == 1) @@ -2988,8 +3021,11 @@ static void P_CheckInvincibilityTimer(player_t *player) else if (leveltime % (TICRATE/7) == 0) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); - sparkle->destscale = player->mo->scale; - P_SetScale(sparkle, player->mo->scale); + if (!P_MobjWasRemoved(sparkle)) + { + sparkle->destscale = player->mo->scale; + P_SetScale(sparkle, player->mo->scale); + } } // Resume normal music stuff. @@ -3044,7 +3080,8 @@ static void P_DoBubbleBreath(player_t *player) y += (P_RandomRange(r, -r)<mo->height>>FRACBITS)<mo->x + stirwaterx, player->mo->y + stirwatery, stirwaterz, MT_SMALLBUBBLE); - bubble->destscale = player->mo->scale; - P_SetScale(bubble,bubble->destscale); + if (!P_MobjWasRemoved(bubble)) + { + bubble->destscale = player->mo->scale; + P_SetScale(bubble,bubble->destscale); + } bubble = P_SpawnMobj( player->mo->x - stirwaterx, player->mo->y - stirwatery, stirwaterz, MT_SMALLBUBBLE); - bubble->destscale = player->mo->scale; - P_SetScale(bubble,bubble->destscale); + if (!P_MobjWasRemoved(bubble)) + { + bubble->destscale = player->mo->scale; + P_SetScale(bubble,bubble->destscale); + } } } @@ -3110,22 +3153,25 @@ static void P_DoPlayerHeadSigns(player_t *player) if (player->pflags & PF_TAGIT && !P_IsLocalPlayer(player)) { mobj_t* it = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG); - it->x = player->mo->x; - it->y = player->mo->y; - it->z = player->mo->z; - it->old_x = player->mo->old_x; - it->old_y = player->mo->old_y; - it->old_z = player->mo->old_z; + if (!P_MobjWasRemoved(it)) + { + it->x = player->mo->x; + it->y = player->mo->y; + it->z = player->mo->z; + it->old_x = player->mo->old_x; + it->old_y = player->mo->old_y; + it->old_z = player->mo->old_z; - if (!(player->mo->eflags & MFE_VERTICALFLIP)) - { - it->z += player->mo->height; - it->old_z += player->mo->height; - } - else - { - it->z -= mobjinfo[MT_TAG].height; - it->old_z -= mobjinfo[MT_TAG].height; + if (!(player->mo->eflags & MFE_VERTICALFLIP)) + { + it->z += player->mo->height; + it->old_z += player->mo->height; + } + else + { + it->z -= mobjinfo[MT_TAG].height; + it->old_z -= mobjinfo[MT_TAG].height; + } } } } @@ -3150,22 +3196,25 @@ static void P_DoPlayerHeadSigns(player_t *player) } sign = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_GOTFLAG); - sign->x = player->mo->x; - sign->y = player->mo->y; - sign->z = player->mo->z + zofs; - sign->old_x = player->mo->old_x; - sign->old_y = player->mo->old_y; - sign->old_z = player->mo->old_z + zofs; - - if (player_is_flipped) + if (!P_MobjWasRemoved(sign)) { - sign->eflags |= MFE_VERTICALFLIP; - } + sign->x = player->mo->x; + sign->y = player->mo->y; + sign->z = player->mo->z + zofs; + sign->old_x = player->mo->old_x; + sign->old_y = player->mo->old_y; + sign->old_z = player->mo->old_z + zofs; - if (player->gotflag & GF_REDFLAG) - sign->frame = 1|FF_FULLBRIGHT; - else //if (player->gotflag & GF_BLUEFLAG) - sign->frame = 2|FF_FULLBRIGHT; + if (player_is_flipped) + { + sign->eflags |= MFE_VERTICALFLIP; + } + + if (player->gotflag & GF_REDFLAG) + sign->frame = 1|FF_FULLBRIGHT; + else //if (player->gotflag & GF_BLUEFLAG) + sign->frame = 2|FF_FULLBRIGHT; + } } } } @@ -4270,8 +4319,11 @@ static void P_DoSuperStuff(player_t *player) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy)) { spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); - spark->destscale = player->mo->scale; - P_SetScale(spark, player->mo->scale); + if (!P_MobjWasRemoved(spark)) + { + spark->destscale = player->mo->scale; + P_SetScale(spark, player->mo->scale); + } } // Ran out of rings while super! @@ -4544,6 +4596,8 @@ static void P_DoSpinDashDust(player_t *player) INT32 prandom[3]; for (i = 0; i <= (leveltime%7)/2; i++) { // 1, 2, 3 or 4 particles particle = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SPINDUST); + if (P_MobjWasRemoved(particle)) + return; if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version P_SetMobjState(particle, S_SPINDUST_BUBBLE1); @@ -4691,7 +4745,8 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (P_IsLocalPlayer(player)) // Only display it on your own view. { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker - P_SetTarget(&visual->target, lockon); + if (!P_MobjWasRemoved(visual)) + P_SetTarget(&visual->target, lockon); } } if ((cmd->buttons & BT_SPIN) && !(player->pflags & PF_SPINDOWN)) @@ -4832,10 +4887,13 @@ void P_DoJumpShield(player_t *player) for (i = 0; i < numangles; i++) { spark = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_THUNDERCOIN_SPARK); - P_InstaThrust(spark, travelangle + i*(ANGLE_MAX/numangles), FixedMul(4*FRACUNIT, spark->scale)); - if (i % 2) - P_SetObjectMomZ(spark, -4*FRACUNIT, false); - spark->fuse = 18; + if (!P_MobjWasRemoved(spark)) + { + P_InstaThrust(spark, travelangle + i*(ANGLE_MAX/numangles), FixedMul(4*FRACUNIT, spark->scale)); + if (i % 2) + P_SetObjectMomZ(spark, -4*FRACUNIT, false); + spark->fuse = 18; + } } #undef limitangle #undef numangles @@ -4942,14 +5000,17 @@ void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type) yo, player->mo->height/2 + zo, type); - P_SetTarget(&missile->target, player->mo); - P_SetScale(missile, (missile->destscale >>= 1)); - missile->angle = ang + movang; - missile->fuse = TICRATE/2; - missile->extravalue2 = (99*FRACUNIT)/100; - missile->momx = xo; - missile->momy = yo; - missile->momz = zo; + if (!P_MobjWasRemoved(missile)) + { + P_SetTarget(&missile->target, player->mo); + P_SetScale(missile, (missile->destscale >>= 1)); + missile->angle = ang + movang; + missile->fuse = TICRATE/2; + missile->extravalue2 = (99*FRACUNIT)/100; + missile->momx = xo; + missile->momy = yo; + missile->momz = zo; + } ang += ANGLE_45; } @@ -5046,8 +5107,11 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock if (dovis) { visual = P_SpawnMobj(lockonshield->x, lockonshield->y, lockonshield->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker - P_SetTarget(&visual->target, lockonshield); - P_SetMobjStateNF(visual, visual->info->spawnstate+1); + if (!P_MobjWasRemoved(visual)) + { + P_SetTarget(&visual->target, lockonshield); + P_SetMobjStateNF(visual, visual->info->spawnstate+1); + } } } } @@ -5153,7 +5217,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (P_IsLocalPlayer(player)) // Only display it on your own view. { visual = P_SpawnMobj(lockonthok->x, lockonthok->y, lockonthok->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker - P_SetTarget(&visual->target, lockonthok); + if (!P_MobjWasRemoved(visual)) + P_SetTarget(&visual->target, lockonthok); } } @@ -6848,10 +6913,14 @@ static void P_DoNiGHTSCapsule(player_t *player) // Spawn a 'pop' for every 2 tics if (!((tictimer - firstpoptic) % 2)) - S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<capsule->y + ((P_SignedRandom()/2)<capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<capsule->x + ((P_SignedRandom()/2)<capsule->y + ((P_SignedRandom()/2)<capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<mo, 0, 0, player->mo->height, MT_GOTEMERALD); - emmo->health = em; // for identification - P_SetTarget(&emmo->target, player->mo); - P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); - P_SetTarget(&player->mo->tracer, emmo); + if (!P_MobjWasRemoved(emmo)) + { + emmo->health = em; // for identification + P_SetTarget(&emmo->target, player->mo); + P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); + P_SetTarget(&player->mo->tracer, emmo); + } } // Okay, we're doing this down here because we're handling time weirdly for co-op special stages @@ -6934,19 +7006,22 @@ static void P_DoNiGHTSCapsule(player_t *player) P_InstaThrust(flicky, flicky->angle, 8*FRACUNIT); }*/ mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); - idya->extravalue2 = player->mare/5; - idya->health = player->mare + 1; // for identification - P_SetTarget(&idya->target, player->mo); - P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); - - if (player->mo->tracer) + if (!P_MobjWasRemoved(idya)) { - P_SetTarget(&idya->hnext, player->mo->tracer); - idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); - if (idya->extravalue1 > player->mo->tracer->extravalue1) - idya->extravalue1 -= (72*ANG1)/idya->extravalue1; + idya->extravalue2 = player->mare/5; + idya->health = player->mare + 1; // for identification + P_SetTarget(&idya->target, player->mo); + P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); + + if (player->mo->tracer) + { + P_SetTarget(&idya->hnext, player->mo->tracer); + idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); + if (idya->extravalue1 > player->mo->tracer->extravalue1) + idya->extravalue1 -= (72*ANG1)/idya->extravalue1; + } + P_SetTarget(&player->mo->tracer, idya); } - P_SetTarget(&player->mo->tracer, idya); } for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mare == player->mare) @@ -7271,19 +7346,25 @@ static void P_NiGHTSMovement(player_t *player) z -= FixedMul(mobjinfo[MT_NIGHTSPARKLE].height, player->mo->scale); firstmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle+ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle+ANGLE_90, spawndist), z, MT_NIGHTSPARKLE); - secondmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle-ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle-ANGLE_90, spawndist), z, MT_NIGHTSPARKLE); - - firstmobj->destscale = secondmobj->destscale = player->mo->scale; - P_SetTarget(&firstmobj->target, player->mo); - P_SetScale(firstmobj, player->mo->scale); - P_SetTarget(&secondmobj->target, player->mo); - P_SetScale(secondmobj, player->mo->scale); - - // Superloop turns sparkles red - if (player->powers[pw_nights_superloop]) + if (!P_MobjWasRemoved(firstmobj)) { - P_SetMobjState(firstmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); - P_SetMobjState(secondmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); + firstmobj->destscale = player->mo->scale; + P_SetTarget(&firstmobj->target, player->mo); + P_SetScale(firstmobj, player->mo->scale); + // Superloop turns sparkles red + if (player->powers[pw_nights_superloop]) + P_SetMobjState(firstmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); + } + secondmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle-ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle-ANGLE_90, spawndist), z, MT_NIGHTSPARKLE); + if (!P_MobjWasRemoved(secondmobj)) + { + secondmobj->destscale = player->mo->scale; + P_SetTarget(&secondmobj->target, player->mo); + P_SetScale(secondmobj, player->mo->scale); + + // Superloop turns sparkles red + if (player->powers[pw_nights_superloop]) + P_SetMobjState(secondmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); } } @@ -7291,9 +7372,12 @@ static void P_NiGHTSMovement(player_t *player) // It also spawns every tic to avoid failed paraloops { mobj_t *helpermobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_NIGHTSLOOPHELPER); - helpermobj->fuse = player->mo->fuse = leveltime; - P_SetTarget(&helpermobj->target, player->mo); - P_SetScale(helpermobj, player->mo->scale); + if (!P_MobjWasRemoved(helpermobj)) + { + helpermobj->fuse = player->mo->fuse = leveltime; + P_SetTarget(&helpermobj->target, player->mo); + P_SetScale(helpermobj, player->mo->scale); + } } if (player->bumpertime) @@ -7482,19 +7566,22 @@ static void P_NiGHTSMovement(player_t *player) mobjtype_t splishtype = (player->mo->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH; mobj_t *water = P_SpawnMobj(player->mo->x, player->mo->y, ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[splishtype].height, player->mo->scale) : player->mo->watertop), splishtype); - if (player->mo->eflags & MFE_GOOWATER) - S_StartSound(water, sfx_ghit); - else if (player->mo->eflags & MFE_TOUCHLAVA) - S_StartSound(water, sfx_splash); - else - S_StartSound(water, sfx_wslap); - if (player->mo->eflags & MFE_VERTICALFLIP) + if (!P_MobjWasRemoved(water)) { - water->flags2 |= MF2_OBJECTFLIP; - water->eflags |= MFE_VERTICALFLIP; + if (player->mo->eflags & MFE_GOOWATER) + S_StartSound(water, sfx_ghit); + else if (player->mo->eflags & MFE_TOUCHLAVA) + S_StartSound(water, sfx_splash); + else + S_StartSound(water, sfx_wslap); + if (player->mo->eflags & MFE_VERTICALFLIP) + { + water->flags2 |= MF2_OBJECTFLIP; + water->eflags |= MFE_VERTICALFLIP; + } + water->destscale = player->mo->scale; + P_SetScale(water, player->mo->scale); } - water->destscale = player->mo->scale; - P_SetScale(water, player->mo->scale); } if (player->mo->momx || player->mo->momy) @@ -7727,6 +7814,8 @@ void P_ElementalFire(player_t *player, boolean cropcircle) for (i = 0; i < numangles; i++) { flame = P_SpawnMobj(player->mo->x, player->mo->y, ground, MT_SPINFIRE); + if (P_MobjWasRemoved(flame)) + continue; flame->flags &= ~MF_NOGRAVITY; P_SetTarget(&flame->target, player->mo); flame->angle = travelangle + i*(ANGLE_MAX/numangles); @@ -7764,6 +7853,8 @@ void P_ElementalFire(player_t *player, boolean cropcircle) } flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); + if (P_MobjWasRemoved(flame)) + continue; P_SetTarget(&flame->target, player->mo); flame->angle = travelangle; flame->fuse = TICRATE*6; @@ -7805,6 +7896,8 @@ void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound) mobj_t *particle; particle = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST); + if (P_MobjWasRemoved(particle)) + return; if (radius >>= FRACBITS) { P_UnsetThingPosition(particle); @@ -8391,19 +8484,22 @@ void P_MovePlayer(player_t *player) mobjtype_t splishtype = (player->mo->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH; mobj_t *water = P_SpawnMobj(player->mo->x - P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius), player->mo->y - P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius), ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[splishtype].height, player->mo->scale) : player->mo->watertop), splishtype); - if (player->mo->eflags & MFE_GOOWATER) - S_StartSound(water, sfx_ghit); - else if (player->mo->eflags & MFE_TOUCHLAVA) - S_StartSound(water, sfx_splash); - else - S_StartSound(water, sfx_wslap); - if (player->mo->eflags & MFE_VERTICALFLIP) + if (!P_MobjWasRemoved(water)) { - water->flags2 |= MF2_OBJECTFLIP; - water->eflags |= MFE_VERTICALFLIP; + if (player->mo->eflags & MFE_GOOWATER) + S_StartSound(water, sfx_ghit); + else if (player->mo->eflags & MFE_TOUCHLAVA) + S_StartSound(water, sfx_splash); + else + S_StartSound(water, sfx_wslap); + if (player->mo->eflags & MFE_VERTICALFLIP) + { + water->flags2 |= MF2_OBJECTFLIP; + water->eflags |= MFE_VERTICALFLIP; + } + water->destscale = player->mo->scale; + P_SetScale(water, player->mo->scale); } - water->destscale = player->mo->scale; - P_SetScale(water, player->mo->scale); } // Little water sound while touching water - just a nicety. @@ -10821,6 +10917,8 @@ static void P_SpawnSparks(mobj_t *mo, angle_t maindir) fixed_t fm = (maindir >> ANGLETOFINESHIFT) & FINEMASK; spark = P_SpawnMobj(mo->x - b2*s + b1*c, mo->y + b2*c + b1*s, mo->z, MT_MINECARTSPARK); + if (P_MobjWasRemoved(spark)) + return; spark->momx = mo->momx + r1 + 8*FINECOSINE(fm); spark->momy = mo->momy + r2 + 8*FINESINE(fm); spark->momz = mo->momz + r3; @@ -12066,17 +12164,20 @@ void P_PlayerThink(player_t *player) if ((player->powers[pw_super] || player->powers[pw_sneakers]) && (player->speed + abs(player->mo->momz)) > FixedMul(20*FRACUNIT,player->mo->scale)) { mobj_t *gmobj = P_SpawnGhostMobj(player->mo); - gmobj->fuse = 2; - if (gmobj->tracer) - gmobj->tracer->fuse = 2; - if (leveltime & 1) + if (!P_MobjWasRemoved(gmobj)) { - gmobj->frame &= ~FF_TRANSMASK; - gmobj->frame |= tr_trans70<fuse = 2; if (gmobj->tracer) + gmobj->tracer->fuse = 2; + if (leveltime & 1) { - gmobj->tracer->frame &= ~FF_TRANSMASK; - gmobj->tracer->frame |= tr_trans70<frame &= ~FF_TRANSMASK; + gmobj->frame |= tr_trans70<tracer) + { + gmobj->tracer->frame &= ~FF_TRANSMASK; + gmobj->tracer->frame |= tr_trans70<normalspeed >= skins[player->skin].normalspeed*2) { mobj_t *ghost = P_SpawnGhostMobj(player->mo); // Spawns afterimages - ghost->fuse = 2; // Makes the images fade quickly - if (ghost->tracer && !P_MobjWasRemoved(ghost->tracer)) - ghost->tracer->fuse = ghost->fuse; + if (!P_MobjWasRemoved(ghost)) + { + ghost->fuse = 2; // Makes the images fade quickly + if (ghost->tracer && !P_MobjWasRemoved(ghost->tracer)) + ghost->tracer->fuse = ghost->fuse; + } } } else if (dashmode) @@ -12889,15 +12993,18 @@ void P_PlayerAfterThink(player_t *player) if (!player->followmobj || P_MobjWasRemoved(player->followmobj)) { P_SetTarget(&player->followmobj, P_SpawnMobjFromMobj(player->mo, 0, 0, 0, player->followitem)); - P_SetTarget(&player->followmobj->tracer, player->mo); - switch (player->followmobj->type) + if (!P_MobjWasRemoved(player->followmobj)) { - case MT_METALJETFUME: - player->followmobj->colorized = true; - break; - default: - player->followmobj->flags2 |= MF2_LINKDRAW; - break; + P_SetTarget(&player->followmobj->tracer, player->mo); + switch (player->followmobj->type) + { + case MT_METALJETFUME: + player->followmobj->colorized = true; + break; + default: + player->followmobj->flags2 |= MF2_LINKDRAW; + break; + } } } From 95d7a486eeb37d3feef16fd29892c62cf966d01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 25 Mar 2023 16:26:31 +0100 Subject: [PATCH 03/85] Implement support for native keyboard layout --- src/console.c | 19 ++++++++----------- src/d_event.h | 1 + src/d_main.c | 6 +++--- src/hu_stuff.c | 45 ++++++++++++++++++++++++++++++++------------- src/sdl/i_video.c | 16 ++++++++++++++++ 5 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/console.c b/src/console.c index 33d59046e..2a48ad80b 100644 --- a/src/console.c +++ b/src/console.c @@ -924,7 +924,7 @@ boolean CON_Responder(event_t *ev) return false; // let go keyup events, don't eat them - if (ev->type != ev_keydown && ev->type != ev_console) + if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console) { if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1]) consdown = false; @@ -951,7 +951,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (! menuactive && bindtable[key]) + if (!menuactive && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); @@ -968,6 +968,12 @@ boolean CON_Responder(event_t *ev) } } + if (ev->type == ev_text) + { + CON_InputAddChar(key); + return true; + } + // Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas if (key == KEY_LSHIFT || key == KEY_RSHIFT || key == KEY_LCTRL || key == KEY_RCTRL @@ -1304,21 +1310,12 @@ boolean CON_Responder(event_t *ev) else if (key == KEY_KPADSLASH) key = '/'; - if (key >= 'a' && key <= 'z') - { - if (capslock ^ shiftdown) - key = shiftxform[key]; - } - else if (shiftdown) - key = shiftxform[key]; - // enter a char into the command prompt if (key < 32 || key > 127) return true; if (input_sel != input_cur) CON_InputDelSelection(); - CON_InputAddChar(key); return true; } diff --git a/src/d_event.h b/src/d_event.h index 5aa435060..7743d8609 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -22,6 +22,7 @@ typedef enum { ev_keydown, ev_keyup, + ev_text, ev_console, ev_mouse, ev_joystick, diff --git a/src/d_main.c b/src/d_main.c index 32f16a282..d660b732e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -190,19 +190,19 @@ void D_ProcessEvents(void) ev = &events[eventtail]; // Set mouse buttons early in case event is eaten later - if (ev->type == ev_keydown || ev->type == ev_keyup) + if (ev->type == ev_keydown || ev->type == ev_keyup || ev->type == ev_text) { // Mouse buttons if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) mouse.buttons |= 1 << (ev->key - KEY_MOUSE1); else mouse.buttons &= ~(1 << (ev->key - KEY_MOUSE1)); } else if ((UINT32)(ev->key - KEY_2MOUSE1) < MOUSEBUTTONS) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) mouse2.buttons |= 1 << (ev->key - KEY_2MOUSE1); else mouse2.buttons &= ~(1 << (ev->key - KEY_2MOUSE1)); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 23c63e98f..04d1642a1 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -77,6 +77,7 @@ patch_t *nto_font[NT_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? +boolean chat_on_first_event; // blocker for first chat input event static char w_chat[HU_MAXMSGLEN + 1]; static size_t c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; @@ -1047,7 +1048,7 @@ boolean HU_Responder(event_t *ev) INT32 c=0; #endif - if (ev->type != ev_keydown) + if (ev->type != ev_keydown && ev->type != ev_text) return false; // only KeyDown events now... @@ -1077,11 +1078,15 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { + if (ev->type == ev_text) + return false; + // enter chat mode if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1]) && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. { chat_on = true; + chat_on_first_event = false; w_chat[0] = 0; teamtalk = false; chat_scrollmedown = true; @@ -1092,6 +1097,7 @@ boolean HU_Responder(event_t *ev) && netgame && !OLD_MUTE) { chat_on = true; + chat_on_first_event = false; w_chat[0] = 0; teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams. chat_scrollmedown = true; @@ -1101,6 +1107,31 @@ boolean HU_Responder(event_t *ev) } else // if chat_on { + if (!chat_on_first_event) + { + // since the text event is sent immediately after the keydown event, + // we need to make sure that nothing is displayed once the chat + // opens, otherwise a 't' would be outputted. + chat_on_first_event = true; + return true; + } + + if (ev->type == ev_text) + { + if ((c < HU_FONTSTART || c > HU_FONTEND || !hu_font[c-HU_FONTSTART]) + && c != ' ') // Allow spaces, of course + { + return false; + } + + if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN) + return true; + + memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1); + w_chat[c_input] = c; + c_input++; + return true; + } // Ignore modifier keys // Note that we do this here so users can still set @@ -1110,8 +1141,6 @@ boolean HU_Responder(event_t *ev) || ev->key == KEY_LALT || ev->key == KEY_RALT) return true; - c = (INT32)ev->key; - // I know this looks very messy but this works. If it ain't broke, don't fix it! // shift LETTERS to uppercase if we have capslock or are holding shift if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) @@ -1194,16 +1223,6 @@ boolean HU_Responder(event_t *ev) else c_input++; } - else if ((c >= HU_FONTSTART && c <= HU_FONTEND && hu_font[c-HU_FONTSTART]) - || c == ' ') // Allow spaces, of course - { - if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN) - return true; - - memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1); - w_chat[c_input] = c; - c_input++; - } else if (c == KEY_BACKSPACE) { if (CHAT_MUTE || c_input <= 0) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d2fbb9006..c25de5fd3 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -686,6 +686,19 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) if (event.key) D_PostEvent(&event); } +static void Impl_HandleTextEvent(SDL_TextInputEvent evt) +{ + event_t event; + event.type = ev_text; + if (evt.text[1] != '\0') + { + // limit ourselves to ASCII for now, we can add UTF-8 support later + return; + } + event.key = evt.text[0]; + D_PostEvent(&event); +} + static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) { static boolean firstmove = true; @@ -934,6 +947,9 @@ void I_GetEvent(void) case SDL_KEYDOWN: Impl_HandleKeyboardEvent(evt.key, evt.type); break; + case SDL_TEXTINPUT: + Impl_HandleTextEvent(evt.text); + break; case SDL_MOUSEMOTION: //if (!mouseMotionOnce) Impl_HandleMouseMotionEvent(evt.motion); From 6896080f4fdca25a764516c66692d52dd8c9063c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 25 Mar 2023 23:08:13 +0100 Subject: [PATCH 04/85] fixup! Implement support for native keyboard layout --- src/hu_stuff.c | 15 +--------- src/m_menu.c | 76 ++++++++++++++++++++++++++++---------------------- 2 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 04d1642a1..a5268f821 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1141,21 +1141,8 @@ boolean HU_Responder(event_t *ev) || ev->key == KEY_LALT || ev->key == KEY_RALT) return true; - // I know this looks very messy but this works. If it ain't broke, don't fix it! - // shift LETTERS to uppercase if we have capslock or are holding shift - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - if (shiftdown ^ capslock) - c = shiftxform[c]; - } - else // if we're holding shift we should still shift non letter symbols - { - if (shiftdown) - c = shiftxform[c]; - } - // pasting. pasting is cool. chat is a bit limited, though :( - if ((c == 'v' || c == 'V') && ctrldown) + if (c == 'v' && ctrldown) { const char *paste; size_t chatlen; diff --git a/src/m_menu.c b/src/m_menu.c index e879e9c14..71e47bc69 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3230,40 +3230,42 @@ boolean M_Responder(event_t *ev) } else if (menuactive) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) { - keydown++; ch = ev->key; - - // added 5-2-98 remap virtual keys (mouse & joystick buttons) - switch (ch) + if (ev->type == ev_keydown) { - case KEY_MOUSE1: - case KEY_JOY1: - ch = KEY_ENTER; - break; - case KEY_JOY1 + 3: - ch = 'n'; - break; - case KEY_MOUSE1 + 1: - case KEY_JOY1 + 1: - ch = KEY_ESCAPE; - break; - case KEY_JOY1 + 2: - ch = KEY_BACKSPACE; - break; - case KEY_HAT1: - ch = KEY_UPARROW; - break; - case KEY_HAT1 + 1: - ch = KEY_DOWNARROW; - break; - case KEY_HAT1 + 2: - ch = KEY_LEFTARROW; - break; - case KEY_HAT1 + 3: - ch = KEY_RIGHTARROW; - break; + keydown++; + // added 5-2-98 remap virtual keys (mouse & joystick buttons) + switch (ch) + { + case KEY_MOUSE1: + case KEY_JOY1: + ch = KEY_ENTER; + break; + case KEY_JOY1 + 3: + ch = 'n'; + break; + case KEY_MOUSE1 + 1: + case KEY_JOY1 + 1: + ch = KEY_ESCAPE; + break; + case KEY_JOY1 + 2: + ch = KEY_BACKSPACE; + break; + case KEY_HAT1: + ch = KEY_UPARROW; + break; + case KEY_HAT1 + 1: + ch = KEY_DOWNARROW; + break; + case KEY_HAT1 + 2: + ch = KEY_LEFTARROW; + break; + case KEY_HAT1 + 3: + ch = KEY_RIGHTARROW; + break; + } } } else if (ev->type == ev_joystick && ev->key == 0 && joywait < I_GetTime()) @@ -3425,8 +3427,11 @@ boolean M_Responder(event_t *ev) // Handle menuitems which need a specific key handling if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) { - if (shiftdown && ch >= 32 && ch <= 127) - ch = shiftxform[ch]; + // ignore ev_keydown events if the key maps to a character, since + // the ev_text event will follow immediately after in that case. + if (ev->type == ev_keydown && ch >= 32 && ch <= 127) + return false; + routine(ch); return true; } @@ -3468,6 +3473,11 @@ boolean M_Responder(event_t *ev) { if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING) { + // ignore ev_keydown events if the key maps to a character, since + // the ev_text event will follow immediately after in that case. + if (ev->type == ev_keydown && ch >= 32 && ch <= 127) + return false; + if (M_ChangeStringCvar(ch)) return true; else From b8f8cc145104d41298585a2c5c84abee7211ade7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 29 Mar 2023 18:58:18 +0200 Subject: [PATCH 05/85] fixup! fixup! Implement support for native keyboard layout --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 2a48ad80b..5571f6bb9 100644 --- a/src/console.c +++ b/src/console.c @@ -951,7 +951,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (!menuactive && bindtable[key]) + if (ev->type == ev_keydown && !menuactive && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); From afe8432c1e5e0fcf40cb5fee9e1e4593352821b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 23 May 2023 17:41:10 +0200 Subject: [PATCH 06/85] fixup! fixup! fixup! Implement support for native keyboard layout --- src/sdl/i_system.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e328bedc2..65f16f0bd 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -601,6 +601,7 @@ void I_GetConsoleEvents(void) else { // push regular character + ev.type = ev_text; ev.key = tty_con.buffer[tty_con.cursor] = key; tty_con.cursor++; // print the current line (this is differential) From 84fe1dfc7de28dd79230fee9f4d21e2259894369 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 23 Jun 2023 23:32:58 +0200 Subject: [PATCH 07/85] Texture scaling (incomplete) --- src/hardware/hw_main.c | 135 ++++++++++++++++++++++------------------- src/lua_maplib.c | 48 +++++++++++++++ src/p_setup.c | 29 +++++++++ src/r_defs.h | 3 + src/r_segs.c | 45 +++++++++++--- 5 files changed, 189 insertions(+), 71 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c2390519e..d1ec05247 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1063,6 +1063,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom fixed_t h, l; // 3D sides and 2s middle textures fixed_t hS, lS; + float xscale, yscale; gl_sidedef = gl_curline->sidedef; gl_linedef = gl_curline->linedef; @@ -1159,33 +1160,35 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpeg %= textureheight[gl_toptexture]; grTex = HWR_GetTexture(gl_toptexture); + xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_top) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_top) * grTex->scaleY; - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_top) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_top) * grTex->scaleX; + wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_top) * xscale; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_top) * xscale; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) { // Unskewed - wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY; - wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY; - wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY; - wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY; + wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * yscale; + wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * yscale; + wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * yscale; + wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * yscale; } else if (gl_linedef->flags & ML_DONTPEGTOP) { // Skewed by top - wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY; - wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * grTex->scaleY; + wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * yscale; + wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * yscale; } else { // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY; - wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * yscale; + wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * yscale; + wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale; } // set top/bottom coords @@ -1219,32 +1222,34 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpeg %= textureheight[gl_bottomtexture]; grTex = HWR_GetTexture(gl_bottomtexture); + xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_bot) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_bot) * grTex->scaleY; - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_bot) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_bot) * grTex->scaleX; + wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * yscale; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_bot) * xscale; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_bot) * xscale; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) { // Unskewed - wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY; - wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY; + wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * yscale; + wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * yscale; + wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * yscale; + wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * yscale; } else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * yscale; + wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * yscale; } else { // Skewed by top - wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY; - wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * grTex->scaleY; + wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * yscale; + wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * yscale; } // set top/bottom coords @@ -1403,16 +1408,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } grTex = HWR_GetTexture(gl_midtexture); + xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; // Left side - wallVerts[3].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[3].t = texturevpeg * yscale; + wallVerts[0].t = (h - l + texturevpeg) * yscale; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; // Right side - wallVerts[2].t = texturevpegslope * grTex->scaleY; - wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[2].t = texturevpegslope * yscale; + wallVerts[1].t = (hS - lS + texturevpegslope) * yscale; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; // set top/bottom coords // Take the texture peg into account, rather than changing the offsets past @@ -1482,24 +1489,26 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpeg = gl_sidedef->rowoffset + gl_sidedef->offsety_mid; grTex = HWR_GetTexture(gl_midtexture); + xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * yscale; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; // Texture correction for slopes if (gl_linedef->flags & ML_NOSKEW) { - wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY; - wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY; - wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY; - wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY; + wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * yscale; + wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * yscale; + wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * yscale; + wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * yscale; } else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { - wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY; + wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * yscale; + wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * yscale; } else { - wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY; - wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY; + wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * yscale; + wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * yscale; } //Set textures properly on single sided walls that are sloped @@ -1646,34 +1655,36 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } grTex = HWR_GetTexture(texnum); + xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; if (!slopeskew) // no skewing { if (attachtobottom) texturevpeg -= *rover->topheight - *rover->bottomheight; - wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; - wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY; - wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; - wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY; + wallVerts[3].t = (*rover->topheight - h + texturevpeg) * yscale; + wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * yscale; + wallVerts[0].t = (*rover->topheight - l + texturevpeg) * yscale; + wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * yscale; } else { if (!attachtobottom) // skew by top { - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; - wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; + wallVerts[0].t = (h - l + texturevpeg) * yscale; + wallVerts[1].t = (hS - lS + texturevpeg) * yscale; } else // skew by bottom { - wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; - wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = texturevpeg * yscale; + wallVerts[3].t = wallVerts[0].t - (h - l) * yscale; + wallVerts[2].t = wallVerts[1].t - (hS - lS) * yscale; } } - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; } if (rover->fofflags & FOF_FOG) { @@ -1782,20 +1793,22 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else { grTex = HWR_GetTexture(texnum); + xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; if (newline) { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid) * yscale; + wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) + sides[newline->sidenum[0]].offsety_mid) * yscale; } else { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid) * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid)) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid) * yscale; + wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid)) * yscale; } - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; } if (rover->fofflags & FOF_FOG) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index f73b3c7d2..942fdf45a 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -172,6 +172,12 @@ enum side_e { side_offsety_mid, side_offsetx_bot, side_offsety_bot, + side_scalex_top, + side_scaley_top, + side_scalex_mid, + side_scaley_mid, + side_scalex_bot, + side_scaley_bot, side_toptexture, side_bottomtexture, side_midtexture, @@ -192,6 +198,12 @@ static const char *const side_opt[] = { "offsety_mid", "offsetx_bot", "offsety_bot", + "scalex_top", + "scaley_top", + "scalex_mid", + "scaley_mid", + "scalex_bot", + "scaley_bot", "toptexture", "bottomtexture", "midtexture", @@ -1127,6 +1139,24 @@ static int side_get(lua_State *L) case side_offsety_bot: lua_pushfixed(L, side->offsety_bot); return 1; + case side_scalex_top: + lua_pushfixed(L, side->scalex_top); + return 1; + case side_scaley_top: + lua_pushfixed(L, side->scaley_top); + return 1; + case side_scalex_mid: + lua_pushfixed(L, side->scalex_mid); + return 1; + case side_scaley_mid: + lua_pushfixed(L, side->scaley_mid); + return 1; + case side_scalex_bot: + lua_pushfixed(L, side->scalex_bot); + return 1; + case side_scaley_bot: + lua_pushfixed(L, side->scaley_bot); + return 1; case side_toptexture: lua_pushinteger(L, side->toptexture); return 1; @@ -1202,6 +1232,24 @@ static int side_set(lua_State *L) case side_offsety_bot: side->offsety_bot = luaL_checkfixed(L, 3); break; + case side_scalex_top: + side->scalex_top = luaL_checkfixed(L, 3); + break; + case side_scaley_top: + side->scaley_top = luaL_checkfixed(L, 3); + break; + case side_scalex_mid: + side->scalex_mid = luaL_checkfixed(L, 3); + break; + case side_scaley_mid: + side->scaley_mid = luaL_checkfixed(L, 3); + break; + case side_scalex_bot: + side->scalex_bot = luaL_checkfixed(L, 3); + break; + case side_scaley_bot: + side->scaley_bot = luaL_checkfixed(L, 3); + break; case side_toptexture: side->toptexture = luaL_checkinteger(L, 3); break; diff --git a/src/p_setup.c b/src/p_setup.c index a10326986..07961b5c7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1243,6 +1243,9 @@ static void P_LoadSidedefs(UINT8 *data) sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; + sd->scalex_top = sd->scalex_mid = sd->scalex_bot = FRACUNIT; + sd->scaley_top = sd->scaley_mid = sd->scaley_bot = FRACUNIT; + P_SetSidedefSector(i, SHORT(msd->sector)); // Special info stored in texture fields! @@ -1792,6 +1795,18 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char sides[i].offsety_mid = atol(val) << FRACBITS; else if (fastcmp(param, "offsety_bottom")) sides[i].offsety_bot = atol(val) << FRACBITS; + else if (fastcmp(param, "scalex_top")) + sides[i].scalex_top = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "scalex_mid")) + sides[i].scalex_mid = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "scalex_bottom")) + sides[i].scalex_bot = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "scaley_top")) + sides[i].scaley_top = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "scaley_mid")) + sides[i].scaley_mid = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "scaley_bottom")) + sides[i].scaley_bot = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "texturetop")) sides[i].toptexture = R_TextureNumForName(val); else if (fastcmp(param, "texturebottom")) @@ -2488,6 +2503,18 @@ static void P_WriteTextmap(void) fprintf(f, "offsetx_bottom = %d;\n", wsides[i].offsetx_bot >> FRACBITS); if (wsides[i].offsety_bot != 0) fprintf(f, "offsety_bottom = %d;\n", wsides[i].offsety_bot >> FRACBITS); + if (wsides[i].scalex_top != FRACUNIT) + fprintf(f, "scalex_top = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_top)); + if (wsides[i].scaley_top != FRACUNIT) + fprintf(f, "scaley_top = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_top)); + if (wsides[i].scalex_mid != FRACUNIT) + fprintf(f, "scalex_mid = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_mid)); + if (wsides[i].scaley_mid != FRACUNIT) + fprintf(f, "scaley_mid = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_mid)); + if (wsides[i].scalex_bot != FRACUNIT) + fprintf(f, "scalex_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_bot)); + if (wsides[i].scaley_bot != FRACUNIT) + fprintf(f, "scaley_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_bot)); if (wsides[i].toptexture > 0 && wsides[i].toptexture < numtextures) fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name); if (wsides[i].bottomtexture > 0 && wsides[i].bottomtexture < numtextures) @@ -2857,6 +2884,8 @@ static void P_LoadTextmap(void) sd->rowoffset = 0; sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; + sd->scalex_top = sd->scalex_mid = sd->scalex_bot = FRACUNIT; + sd->scaley_top = sd->scaley_mid = sd->scaley_bot = FRACUNIT; sd->toptexture = R_TextureNumForName("-"); sd->midtexture = R_TextureNumForName("-"); sd->bottomtexture = R_TextureNumForName("-"); diff --git a/src/r_defs.h b/src/r_defs.h index 963d655b1..7f440179f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -563,6 +563,9 @@ typedef struct fixed_t offsetx_top, offsetx_mid, offsetx_bot; fixed_t offsety_top, offsety_mid, offsety_bot; + fixed_t scalex_top, scalex_mid, scalex_bot; + fixed_t scaley_top, scaley_mid, scaley_bot; + // Texture indices. // We do not maintain names here. INT32 toptexture, bottomtexture, midtexture; diff --git a/src/r_segs.c b/src/r_segs.c index 5acca9b17..0a23699d2 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -42,6 +42,10 @@ angle_t rw_normalangle; // angle to line origin angle_t rw_angle1; fixed_t rw_distance; +// Horizontal scaling hack shenanigans. +fixed_t rw_distance_scalex_top; +fixed_t rw_distance_scalex_mid; +fixed_t rw_distance_scalex_bot; // // regular wall @@ -69,6 +73,7 @@ static fixed_t *rw_bsilheight = NULL; static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; +static fixed_t topxscale, topyscale, midxscale, midyscale, botxscale, botyscale; static lighttable_t **walllights; static INT16 *maskedtexturecol; @@ -1093,6 +1098,9 @@ static void R_RenderSegLoop (void) INT32 mid; fixed_t texturecolumn = 0; + fixed_t texturecolumn_top = 0; + fixed_t texturecolumn_mid = 0; + fixed_t texturecolumn_bot = 0; fixed_t oldtexturecolumn = -1; INT32 top; INT32 bottom; @@ -1261,6 +1269,9 @@ static void R_RenderSegLoop (void) // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); + texturecolumn_top = (rw_offset_top - FixedMul(FINETANGENT(angle),rw_distance_scalex_top))>>FRACBITS; + texturecolumn_mid = (rw_offset_mid - FixedMul(FINETANGENT(angle),rw_distance_scalex_mid))>>FRACBITS; + texturecolumn_bot = (rw_offset_bot - FixedMul(FINETANGENT(angle),rw_distance_scalex_bot))>>FRACBITS; if (oldtexturecolumn != -1) { rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); @@ -1335,8 +1346,9 @@ static void R_RenderSegLoop (void) { dc_yl = yl; dc_yh = yh; - dc_texturemid = rw_midtexturemid; - dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS)); + dc_texturemid = FixedMul(rw_midtexturemid, midyscale); + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, midyscale); + dc_source = R_GetColumn(midtexture, texturecolumn_mid); dc_texheight = textureheight[midtexture]>>FRACBITS; //profile stuff --------------------------------------------------------- @@ -1396,8 +1408,9 @@ static void R_RenderSegLoop (void) { dc_yl = yl; dc_yh = mid; - dc_texturemid = rw_toptexturemid; - dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS)); + dc_texturemid = FixedMul(rw_toptexturemid, topyscale); + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, topyscale); + dc_source = R_GetColumn(toptexture, texturecolumn_top); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1432,9 +1445,9 @@ static void R_RenderSegLoop (void) { dc_yl = mid; dc_yh = yh; - dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn + (rw_offset_bot>>FRACBITS)); + dc_texturemid = FixedMul(rw_bottomtexturemid, botyscale); + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, botyscale); + dc_source = R_GetColumn(bottomtexture, texturecolumn_bot); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); floorclip[rw_x] = (INT16)mid; @@ -2305,10 +2318,22 @@ void R_StoreWallRange(INT32 start, INT32 stop) /// don't use texture offset for splats rw_offset2 = rw_offset + curline->offset; + + // Per-texture scaling, offsetting. + topxscale = sidedef->scalex_top; + midxscale = sidedef->scalex_mid; + botxscale = sidedef->scalex_bot; + topyscale = sidedef->scaley_top; + midyscale = sidedef->scaley_mid; + botyscale = sidedef->scaley_bot; + rw_offset_top = FixedMul(rw_offset + curline->offset, topxscale) + sidedef->textureoffset + sidedef->offsetx_top; + rw_offset_mid = FixedMul(rw_offset + curline->offset, midxscale) + sidedef->textureoffset + sidedef->offsetx_mid; + rw_offset_bot = FixedMul(rw_offset + curline->offset, botxscale) + sidedef->textureoffset + sidedef->offsetx_bot; + rw_distance_scalex_top = FixedMul(rw_distance, topxscale); + rw_distance_scalex_mid = FixedMul(rw_distance, midxscale); + rw_distance_scalex_bot = FixedMul(rw_distance, botxscale); + rw_offset += sidedef->textureoffset + curline->offset; - rw_offset_top = sidedef->offsetx_top; - rw_offset_mid = sidedef->offsetx_mid; - rw_offset_bot = sidedef->offsetx_bot; rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; // calculate light table From 5bee4e1cd881703d7727b6261c9a567db8b9f18f Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 28 Jun 2023 18:44:23 +0200 Subject: [PATCH 08/85] Don't scale texture offsets in Software --- src/r_segs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 0a23699d2..768c4be81 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2326,9 +2326,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) topyscale = sidedef->scaley_top; midyscale = sidedef->scaley_mid; botyscale = sidedef->scaley_bot; - rw_offset_top = FixedMul(rw_offset + curline->offset, topxscale) + sidedef->textureoffset + sidedef->offsetx_top; - rw_offset_mid = FixedMul(rw_offset + curline->offset, midxscale) + sidedef->textureoffset + sidedef->offsetx_mid; - rw_offset_bot = FixedMul(rw_offset + curline->offset, botxscale) + sidedef->textureoffset + sidedef->offsetx_bot; + rw_offset_top = FixedMul(rw_offset + curline->offset + sidedef->textureoffset + sidedef->offsetx_top, topxscale); + rw_offset_mid = FixedMul(rw_offset + curline->offset + sidedef->textureoffset + sidedef->offsetx_mid, midxscale); + rw_offset_bot = FixedMul(rw_offset + curline->offset + sidedef->textureoffset + sidedef->offsetx_bot, botxscale); rw_distance_scalex_top = FixedMul(rw_distance, topxscale); rw_distance_scalex_mid = FixedMul(rw_distance, midxscale); rw_distance_scalex_bot = FixedMul(rw_distance, botxscale); From 4c4584f9d1e95a63eb82d76d16182ed9b9d76bfb Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 28 Jun 2023 21:04:34 +0200 Subject: [PATCH 09/85] Fix Y offsets on scaled textures in OpenGL --- src/hardware/hw_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d1ec05247..a8992a28d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1146,18 +1146,20 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // check TOP TEXTURE if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) { + fixed_t texheight = FixedDiv(textureheight[gl_toptexture], gl_sidedef->scaley_top); + // PEGGING if (gl_linedef->flags & ML_DONTPEGTOP) texturevpeg = 0; else if (gl_linedef->flags & ML_SKEWTD) - texturevpeg = worldhigh + textureheight[gl_toptexture] - worldtop; + texturevpeg = worldhigh + texheight - worldtop; else - texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight; + texturevpeg = gl_backsector->ceilingheight + texheight - gl_frontsector->ceilingheight; texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpeg %= textureheight[gl_toptexture]; + texturevpeg %= texheight; grTex = HWR_GetTexture(gl_toptexture); xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_top) * grTex->scaleX; @@ -1219,7 +1221,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bot; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpeg %= textureheight[gl_bottomtexture]; + texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bot); grTex = HWR_GetTexture(gl_bottomtexture); xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_bot) * grTex->scaleX; From cb30411e4962f6843be8cdd8c3b3fb31827e7ec6 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 29 Jun 2023 09:34:00 +0200 Subject: [PATCH 10/85] Fix broken two-sided midtextures in Software --- 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 768c4be81..5bb4f4836 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1466,7 +1466,7 @@ static void R_RenderSegLoop (void) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)(texturecolumn + (rw_offset_mid>>FRACBITS)); + maskedtexturecol[rw_x] = (INT16)texturecolumn_mid; if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? From cc852ef0fe72dd13ea7e254b7a5018ad9899919f Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 29 Jun 2023 11:46:12 +0200 Subject: [PATCH 11/85] Fix Y scaling on 2-sided midtextures in OpenGL --- src/hardware/hw_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a8992a28d..2db109921 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1272,6 +1272,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) { sector_t *front, *back; + fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid); INT32 repeats; if (gl_linedef->frontsector->heightsec != -1) @@ -1300,8 +1301,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else low = back->floorheight; - repeats = (high - low) / textureheight[gl_midtexture]; - if ((high - low) % textureheight[gl_midtexture]) + repeats = (high - low) / texheight; + if ((high - low) % texheight) repeats++; // tile an extra time to fill the gap -- Monster Iestyn } else @@ -1324,7 +1325,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom popenbottom = popenbottomslope = back->floorheight; } else - { + { popentop = min(worldtop, worldhigh); popenbottom = max(worldbottom, worldlow); popentopslope = min(worldtopslope, worldhighslope); @@ -1332,7 +1333,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } // Find the wall's coordinates - fixed_t midtexheight = textureheight[gl_midtexture] * repeats; + fixed_t midtexheight = texheight * repeats; // Texture is not skewed if (gl_linedef->flags & ML_NOSKEW) From cffce823711af827f411a89b49d064994cea52a3 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 29 Jun 2023 14:19:16 +0200 Subject: [PATCH 12/85] Support FOF texture scaling in OpenGL --- src/hardware/hw_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2db109921..7ec0f76c2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1658,8 +1658,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } grTex = HWR_GetTexture(texnum); - xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; + xscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scalex_mid) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scaley_mid) * grTex->scaleY; if (!slopeskew) // no skewing { @@ -1796,8 +1796,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else { grTex = HWR_GetTexture(texnum); - xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; + xscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scalex_mid) * grTex->scaleX; + yscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scaley_mid) * grTex->scaleY; if (newline) { From e0ea677ca42c43715332c9a12b8f55e3e89f2900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 30 Aug 2023 19:32:13 +0200 Subject: [PATCH 13/85] Make chat spam protection more configurable --- src/d_netcmd.c | 5 ++++- src/g_game.c | 4 +++- src/g_game.h | 2 +- src/hu_stuff.c | 36 +++++++++++++++++++++++++----------- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 33281e992..4d9779a97 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -619,6 +619,10 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_addons_folder); CV_RegisterVar(&cv_dummyconsvar); + + CV_RegisterVar(&cv_chatspamprotection); + CV_RegisterVar(&cv_chatspamspeed); + CV_RegisterVar(&cv_chatspamburst); } // ========================================================================= @@ -762,7 +766,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_chatheight); CV_RegisterVar(&cv_chatwidth); CV_RegisterVar(&cv_chattime); - CV_RegisterVar(&cv_chatspamprotection); CV_RegisterVar(&cv_chatbacktint); CV_RegisterVar(&cv_consolechat); CV_RegisterVar(&cv_chatnotifications); diff --git a/src/g_game.c b/src/g_game.c index 9780bcd4d..4dc84b328 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -304,7 +304,9 @@ consvar_t cv_chatheight= CVAR_INIT ("chatheight", "8", CV_SAVE, chatheight_cons_ consvar_t cv_chatnotifications= CVAR_INIT ("chatnotifications", "On", CV_SAVE, CV_OnOff, NULL); // chat spam protection (why would you want to disable that???) -consvar_t cv_chatspamprotection= CVAR_INIT ("chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_chatspamprotection= CVAR_INIT ("chatspamprotection", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_chatspamspeed= CVAR_INIT ("chatspamspeed", "35", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL); +consvar_t cv_chatspamburst= CVAR_INIT ("chatspamburst", "3", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL); // minichat text background consvar_t cv_chatbacktint = CVAR_INIT ("chatbacktint", "On", CV_SAVE, CV_OnOff, NULL); diff --git a/src/g_game.h b/src/g_game.h index a8c285f79..cdaf7d2f5 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -51,7 +51,7 @@ extern consvar_t cv_pauseifunfocused; // used in game menu extern consvar_t cv_tutorialprompt; -extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard; +extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_chatspamspeed, cv_chatspamburst, cv_compactscoreboard; extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 091e2b2fb..11c2a9e3d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -630,7 +630,9 @@ static void Command_CSay_f(void) DoSayCommand(0, 1, HU_CSAY); } -static tic_t stop_spamming[MAXPLAYERS]; + +static tic_t spam_tokens[MAXPLAYERS]; +static tic_t spam_tics[MAXPLAYERS]; /** Receives a message, processing an ::XD_SAY command. * \sa DoSayCommand @@ -682,14 +684,14 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // before we do anything, let's verify the guy isn't spamming, get this easier on us. //if (stop_spamming[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) - if (stop_spamming[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY)) + if (spam_tokens[playernum] <= 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) { CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); - stop_spamming[playernum] = 4; + spam_tics[playernum] = 0; spam_eatmsg = 1; } else - stop_spamming[playernum] = 4; // you can hold off for 4 tics, can you? + spam_tokens[playernum] -= 1; // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. @@ -871,6 +873,25 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // void HU_Ticker(void) { + // do this server-side, too + if (netgame) + { + size_t i = 0; + + // handle spam while we're at it: + for(; (i= (tic_t)cv_chatspamspeed.value) + { + spam_tokens[i]++; + spam_tics[i] = 0; + } + } + } + } + if (dedicated) return; @@ -894,13 +915,6 @@ void HU_Ticker(void) { size_t i = 0; - // handle spam while we're at it: - for(; (i 0) - stop_spamming[i]--; - } - // handle chat timers for (i=0; (i Date: Wed, 14 Jun 2023 13:15:05 +0200 Subject: [PATCH 14/85] Add shortcuts for current/next map to map command --- src/g_game.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index fae311694..f415b45db 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5373,16 +5373,27 @@ void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc) INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) { boolean usemapcode = false; - INT32 newmapnum; - - size_t mapnamelen; - + size_t mapnamelen = strlen(mapname); char *p; - mapnamelen = strlen(mapname); - - if (mapnamelen == 2)/* maybe two digit code */ + if (mapnamelen == 1) + { + if (strcmp(mapname, "*") == 0) // current map + return gamemap; + else if (strcmp(mapname, "+") == 0 && mapheaderinfo[gamemap-1]) // next map + { + newmapnum = mapheaderinfo[gamemap-1]->nextlevel; + if (newmapnum < 1 || newmapnum > NUMMAPS) + { + CONS_Alert(CONS_ERROR, M_GetText("NextLevel (%d) is not a valid map.\n"), newmapnum); + return 0; + } + else + return newmapnum; + } + } + else if (mapnamelen == 2)/* maybe two digit code */ { if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) )) usemapcode = true; From 4fc5c9af34806eaa726202d6e43e6fce704b28fe Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 10 Oct 2023 16:36:52 +0200 Subject: [PATCH 15/85] Simplify single-character checks --- src/g_game.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index f415b45db..5eec1cd50 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5379,9 +5379,9 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) if (mapnamelen == 1) { - if (strcmp(mapname, "*") == 0) // current map + if (mapname[0] == '*') // current map return gamemap; - else if (strcmp(mapname, "+") == 0 && mapheaderinfo[gamemap-1]) // next map + else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map { newmapnum = mapheaderinfo[gamemap-1]->nextlevel; if (newmapnum < 1 || newmapnum > NUMMAPS) From 9f116c7c9ef29b77e42df8ccae94087c81fc3285 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 18 Oct 2023 16:50:06 +0200 Subject: [PATCH 16/85] Fix mouse events not being fired when the mouse is ungrabbed --- src/sdl/i_video.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 590d7d142..a70e5a860 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -382,10 +382,8 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) return 0; } -static boolean IgnoreMouse(void) +static boolean ShouldIgnoreMouse(void) { - if (cv_alwaysgrabmouse.value) - return false; if (menuactive) return !M_MouseNeeded(); if (paused || con_destlines || chat_on) @@ -393,11 +391,20 @@ static boolean IgnoreMouse(void) if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && gamestate != GS_CONTINUING && gamestate != GS_CUTSCENE) return true; - if (!mousegrabbedbylua) - return true; return false; } +static boolean ShouldGrabMouse(void) +{ + if (cv_alwaysgrabmouse.value) + return true; + if (ShouldIgnoreMouse()) + return false; + if (!mousegrabbedbylua) + return false; + return true; +} + static void SDLdoGrabMouse(void) { SDL_ShowCursor(SDL_DISABLE); @@ -424,7 +431,7 @@ void I_UpdateMouseGrab(void) { if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL && SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window - && USE_MOUSEINPUT && !IgnoreMouse()) + && USE_MOUSEINPUT && ShouldGrabMouse()) SDLdoGrabMouse(); } @@ -640,7 +647,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) } //else firsttimeonmouse = SDL_FALSE; - if (USE_MOUSEINPUT && !IgnoreMouse()) + if (USE_MOUSEINPUT && ShouldGrabMouse()) SDLdoGrabMouse(); } else if (!mousefocus && !kbfocus) @@ -692,7 +699,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) if (USE_MOUSEINPUT) { - if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IgnoreMouse() && !firstmove)) + if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (!ShouldGrabMouse() && !firstmove)) { SDLdoUngrabMouse(); firstmove = false; @@ -745,7 +752,7 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type) // this apparently makes a mouse button down event but not a mouse button up event, // resulting in whatever key was pressed down getting "stuck" if we don't ignore it. // -- Monster Iestyn (28/05/18) - if (SDL_GetMouseFocus() != window || IgnoreMouse()) + if (SDL_GetMouseFocus() != window || ShouldIgnoreMouse()) return; /// \todo inputEvent.button.which @@ -1127,7 +1134,7 @@ void I_StartupMouse(void) } else firsttimeonmouse = SDL_FALSE; - if (cv_usemouse.value && !IgnoreMouse()) + if (cv_usemouse.value && ShouldGrabMouse()) SDLdoGrabMouse(); else SDLdoUngrabMouse(); From b98d9dfe522fa17ecae47632543fc1b2ce16d121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 26 Oct 2023 23:43:07 +0200 Subject: [PATCH 17/85] Use nanosleep for I_SleepDuration on *nix --- src/i_time.c | 35 ----------------------------------- src/sdl/i_system.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/i_time.c b/src/i_time.c index fae26abed..aa18f6e36 100644 --- a/src/i_time.c +++ b/src/i_time.c @@ -88,38 +88,3 @@ void I_UpdateTime(fixed_t timescale) g_time.timefrac = FLOAT_TO_FIXED(fractional); } } - -void I_SleepDuration(precise_t duration) -{ - UINT64 precision = I_GetPrecisePrecision(); - INT32 sleepvalue = cv_sleep.value; - UINT64 delaygranularity; - precise_t cur; - precise_t dest; - - { - double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS)); - delaygranularity = (UINT64)gran; - } - - cur = I_GetPreciseTime(); - dest = cur + duration; - - // the reason this is not dest > cur is because the precise counter may wrap - // two's complement arithmetic is our friend here, though! - // e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1 - // 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3 - while ((INT64)(dest - cur) > 0) - { - // If our cv_sleep value exceeds the remaining sleep duration, use the - // hard sleep function. - if (sleepvalue > 0 && (dest - cur) > delaygranularity) - { - I_Sleep(sleepvalue); - } - - // Otherwise, this is a spinloop. - - cur = I_GetPreciseTime(); - } -} diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index b05f40ee3..acc57f8d2 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2265,6 +2265,52 @@ void I_Sleep(UINT32 ms) SDL_Delay(ms); } +void I_SleepDuration(precise_t duration) +{ +#if defined(__linux__) || defined(__FreeBSD__) + UINT64 precision = I_GetPrecisePrecision(); + struct timespec ts = { + .tv_sec = duration / precision, + .tv_nsec = duration * 1000000000 / precision % 1000000000, + }; + int status; + do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + while (status == EINTR); +#else + UINT64 precision = I_GetPrecisePrecision(); + INT32 sleepvalue = cv_sleep.value; + UINT64 delaygranularity; + precise_t cur; + precise_t dest; + + { + double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS)); + delaygranularity = (UINT64)gran; + } + + cur = I_GetPreciseTime(); + dest = cur + duration; + + // the reason this is not dest > cur is because the precise counter may wrap + // two's complement arithmetic is our friend here, though! + // e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1 + // 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3 + while ((INT64)(dest - cur) > 0) + { + // If our cv_sleep value exceeds the remaining sleep duration, use the + // hard sleep function. + if (sleepvalue > 0 && (dest - cur) > delaygranularity) + { + I_Sleep(sleepvalue); + } + + // Otherwise, this is a spinloop. + + cur = I_GetPreciseTime(); + } +#endif +} + #ifdef NEWSIGNALHANDLER ATTRNORETURN static FUNCNORETURN void newsignalhandler_Warn(const char *pr) { From e92787e75f7a773f78222d37d411bf2fde8c35a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 28 Oct 2023 15:44:45 +0200 Subject: [PATCH 18/85] Fix Windows build --- src/i_time.c | 6 ------ src/sdl/i_system.c | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/i_time.c b/src/i_time.c index aa18f6e36..39854b242 100644 --- a/src/i_time.c +++ b/src/i_time.c @@ -30,12 +30,6 @@ static precise_t enterprecise, oldenterprecise; static fixed_t entertic, oldentertics; static double tictimer; -// A little more than the minimum sleep duration on Windows. -// May be incorrect for other platforms, but we don't currently have a way to -// query the scheduler granularity. SDL will do what's needed to make this as -// low as possible though. -#define MIN_SLEEP_DURATION_MS 2.1 - tic_t I_GetTime(void) { return g_time.time; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index acc57f8d2..3da4e6152 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -41,6 +41,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #undef SystemFunction036 +// A little more than the minimum sleep duration on Windows. +// May be incorrect for other platforms, but we don't currently have a way to +// query the scheduler granularity. SDL will do what's needed to make this as +// low as possible though. +#define MIN_SLEEP_DURATION_MS 2.1 + #endif #include #include From 9013ceeacc9660fbe4f3dd2249a061dc77211929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 1 Nov 2023 17:31:17 +0100 Subject: [PATCH 19/85] Fix buffer overflow when when fetching typenames on freeslots --- src/p_tick.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_tick.c b/src/p_tick.c index 444b68d2f..b0155d780 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -236,6 +236,8 @@ static const char *MobjTypeName(const mobj_t *mobj) { if (mobj->thinker.debug_mobjtype != MT_NULL) { + if (mobj->thinker.debug_mobjtype >= MT_FIRSTFREESLOT) + return "MT_FREESLOT"; return MOBJTYPE_LIST[mobj->thinker.debug_mobjtype]; } } From 7e7ff84f0806906f2019aedb8ab6d48d18744075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 1 Nov 2023 17:18:26 +0100 Subject: [PATCH 20/85] Fix buffer overflow when tag bits are set --- src/taglist.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/taglist.c b/src/taglist.c index e4e385b9e..7bd004627 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -180,10 +180,10 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id) if (Taggroup_Find(group, id) != (size_t)-1) return; - if (! in_bit_array(tags_available, tag)) + if (! in_bit_array(tags_available, (UINT16)tag)) { num_tags++; - set_bit_array(tags_available, tag); + set_bit_array(tags_available, (UINT16)tag); } // Create group if empty. @@ -220,10 +220,10 @@ static void Taggroup_Add_Init(taggroup_t *garray[], const mtag_t tag, size_t id) group = garray[(UINT16)tag]; - if (! in_bit_array(tags_available, tag)) + if (! in_bit_array(tags_available, (UINT16)tag)) { num_tags++; - set_bit_array(tags_available, tag); + set_bit_array(tags_available, (UINT16)tag); } // Create group if empty. @@ -271,7 +271,7 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id) if (group->count == 1 && total_elements_with_tag(tag) == 1) { num_tags--; - unset_bit_array(tags_available, tag); + unset_bit_array(tags_available, (UINT16)tag); } // Strip away taggroup if no elements left. From ede41c474b11767ac584957b944a95a5e8201744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 1 Nov 2023 18:30:37 +0100 Subject: [PATCH 21/85] Pass -fwrapv to GCC compilation flags --- src/Makefile.d/versions.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk index d2877b374..73d352138 100644 --- a/src/Makefile.d/versions.mk +++ b/src/Makefile.d/versions.mk @@ -160,6 +160,10 @@ opts+=-O0 endif endif +ifdef GCC45 +opts+=-fwrapv +endif + ifdef VALGRIND ifdef GCC46 WFLAGS+=-Wno-error=unused-but-set-variable From 6d650728f6594d751de6291b40b567f50204bc90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 2 Nov 2023 21:58:36 +0100 Subject: [PATCH 22/85] Update CMake and XCode build systems --- src/CMakeLists.txt | 4 ++++ src/Makefile.d/detect.mk | 3 ++- src/Makefile.d/versions.mk | 2 +- src/sdl/macosx/Srb2mac.pbproj/project.pbxproj | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 22c1def27..5fbc7002a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -260,6 +260,10 @@ target_compile_options(SRB2SDL2 PRIVATE -Wdisabled-optimization > + $<$,3.4.0>: + -fwrapv + > + $<$,4.0.0>: -Wold-style-definition -Wmissing-field-initializers diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk index 9e2736946..3d9fc2766 100644 --- a/src/Makefile.d/detect.mk +++ b/src/Makefile.d/detect.mk @@ -65,7 +65,8 @@ gcc_versions:=\ 75 74 73 72 71 70\ 64 63 62 61 60\ 55 54 53 52 51 50\ - 49 48 47 46 45 44 43 42 41 40 + 49 48 47 46 45 44 43 42 41 40\ + 34 latest_gcc_version:=13.2 diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk index 73d352138..40ccd9f26 100644 --- a/src/Makefile.d/versions.mk +++ b/src/Makefile.d/versions.mk @@ -160,7 +160,7 @@ opts+=-O0 endif endif -ifdef GCC45 +ifdef GCC34 opts+=-fwrapv endif diff --git a/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj b/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj index 909bb2ced..40f580be1 100644 --- a/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj @@ -2133,7 +2133,7 @@ INSTALL_PATH = "$(HOME)/Applications"; JAVA_COMPILER_DEBUGGING_SYMBOLS = NO; OPTIMIZATION_CFLAGS = "-O2"; - OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -Winline -fno-strict-aliasing"; + OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -Winline -fno-strict-aliasing -fwrapv"; OTHER_REZFLAGS = ""; PREBINDING = NO; PRODUCT_NAME = Srb2; From 7e8c0d87a2d616e5e916b230623a44c1248164ce Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Thu, 2 Nov 2023 21:21:05 +0000 Subject: [PATCH 23/85] Return freeslot name instead of MT_FREESLOT (thanks Zwip-Zwap_Zapony) --- src/p_tick.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/p_tick.c b/src/p_tick.c index b0155d780..1c658bc1e 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -226,23 +226,22 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker) #ifdef PARANOIA static const char *MobjTypeName(const mobj_t *mobj) { + mobjtype_t type; actionf_p1 p1 = mobj->thinker.function.acp1; if (p1 == (actionf_p1)P_MobjThinker) - { - return MOBJTYPE_LIST[mobj->type]; - } - else if (p1 == (actionf_p1)P_RemoveThinkerDelayed) - { - if (mobj->thinker.debug_mobjtype != MT_NULL) - { - if (mobj->thinker.debug_mobjtype >= MT_FIRSTFREESLOT) - return "MT_FREESLOT"; - return MOBJTYPE_LIST[mobj->thinker.debug_mobjtype]; - } - } + type = mobj->type; + else if (p1 == (actionf_p1)P_RemoveThinkerDelayed && mobj->thinker.debug_mobjtype != MT_NULL) + type = mobj->thinker.debug_mobjtype; + else + return ""; - return ""; + if (type < 0 || type >= NUMMOBJTYPES || (type >= MT_FIRSTFREESLOT && !FREE_MOBJS[type - MT_FIRSTFREESLOT])) + return ""; + else if (type >= MT_FIRSTFREESLOT) + return FREE_MOBJS[type - MT_FIRSTFREESLOT]; // This doesn't include "MT_"... + else + return MOBJTYPE_LIST[type]; } static const char *MobjThinkerName(const mobj_t *mobj) From 80475adabf6fb7625b0b955dc8c5eeb18006757d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 4 Nov 2023 11:48:20 +0100 Subject: [PATCH 24/85] Always apply -fwrapv on builds --- src/CMakeLists.txt | 6 ++---- src/Makefile | 2 +- src/Makefile.d/detect.mk | 3 +-- src/Makefile.d/versions.mk | 4 ---- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5fbc7002a..405fa9572 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -253,6 +253,7 @@ target_compile_options(SRB2SDL2 PRIVATE -Winline -Wformat-y2k -Wformat-security + -fwrapv $<$,2.9.5>: -Wno-div-by-zero @@ -260,10 +261,6 @@ target_compile_options(SRB2SDL2 PRIVATE -Wdisabled-optimization > - $<$,3.4.0>: - -fwrapv - > - $<$,4.0.0>: -Wold-style-definition -Wmissing-field-initializers @@ -326,6 +323,7 @@ target_compile_options(SRB2SDL2 PRIVATE -Wno-error=non-literal-null-conversion -Wno-error=constant-conversion -Wno-error=unused-but-set-variable + -fwrapv > # C, MSVC diff --git a/src/Makefile b/src/Makefile index a0a18be76..b730cd0bb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -164,7 +164,7 @@ sources:= makedir:=../make # -DCOMPVERSION: flag to use comptime.h -opts:=-DCOMPVERSION -g +opts:=-DCOMPVERSION -g -fwrapv libs:= # This is a list of variables names, of which if defined, diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk index 3d9fc2766..9e2736946 100644 --- a/src/Makefile.d/detect.mk +++ b/src/Makefile.d/detect.mk @@ -65,8 +65,7 @@ gcc_versions:=\ 75 74 73 72 71 70\ 64 63 62 61 60\ 55 54 53 52 51 50\ - 49 48 47 46 45 44 43 42 41 40\ - 34 + 49 48 47 46 45 44 43 42 41 40 latest_gcc_version:=13.2 diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk index 40ccd9f26..d2877b374 100644 --- a/src/Makefile.d/versions.mk +++ b/src/Makefile.d/versions.mk @@ -160,10 +160,6 @@ opts+=-O0 endif endif -ifdef GCC34 -opts+=-fwrapv -endif - ifdef VALGRIND ifdef GCC46 WFLAGS+=-Wno-error=unused-but-set-variable From 5deee87bd293430a201e2ced5748d07791c18a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 4 Nov 2023 19:12:23 +0100 Subject: [PATCH 25/85] Fix keyhandler menus not blocking in-game movement --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 56d82eed2..68974d61a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3376,7 +3376,7 @@ boolean M_Responder(event_t *ev) // ignore ev_keydown events if the key maps to a character, since // the ev_text event will follow immediately after in that case. if (ev->type == ev_keydown && ch >= 32 && ch <= 127) - return false; + return true; routine(ch); return true; From 4cf1d7fe10ad2dee57c59679a74e1148c38f3779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 5 Nov 2023 13:52:23 +0100 Subject: [PATCH 26/85] Cache and reuse removed mobjs when spawning mobjs --- src/d_think.h | 1 + src/p_local.h | 1 + src/p_mobj.c | 17 +++++++++++++++-- src/p_setup.c | 1 + src/p_tick.c | 12 +++++++++++- 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/d_think.h b/src/d_think.h index efc1589bf..589124587 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -51,6 +51,7 @@ typedef struct thinker_s // killough 11/98: count of how many other objects reference // this one using pointers. Used for garbage collection. INT32 references; + boolean cachable; #ifdef PARANOIA INT32 debug_mobjtype; diff --git a/src/p_local.h b/src/p_local.h index c26c09860..70eb3435e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -71,6 +71,7 @@ typedef enum NUM_THINKERLISTS } thinklistnum_t; /**< Thinker lists. */ extern thinker_t thlist[]; +extern mobj_t *mobjcache; void P_InitThinkers(void); void P_AddThinker(const thinklistnum_t n, thinker_t *thinker); diff --git a/src/p_mobj.c b/src/p_mobj.c index 7a5aaf424..f424fba06 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -45,6 +45,8 @@ actioncache_t actioncachehead; static mobj_t *overlaycap = NULL; +mobj_t *mobjcache = NULL; + void P_InitCachedActions(void) { actioncachehead.prev = actioncachehead.next = &actioncachehead; @@ -10659,7 +10661,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) type = MT_RAY; } - mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); + if (mobjcache != NULL) + { + mobj = mobjcache; + mobjcache = mobjcache->hnext; + memset(mobj, 0, sizeof(*mobj)); + } + else + { + mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); + } // this is officially a mobj, declared as soon as possible. mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; @@ -11214,7 +11225,9 @@ void P_RemoveMobj(mobj_t *mobj) INT32 prevreferences; if (!mobj->thinker.references) { - Z_Free(mobj); // No refrrences? Can be removed immediately! :D + // no references, dump it directly in the mobj cache + mobj->hnext = mobjcache; + mobjcache = mobj; return; } diff --git a/src/p_setup.c b/src/p_setup.c index 7f6fcd36c..ab6b68bd1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7806,6 +7806,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) Patch_FreeTag(PU_PATCH_LOWPRIORITY); Patch_FreeTag(PU_PATCH_ROTATED); Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); + mobjcache = NULL; R_InitializeLevelInterpolators(); diff --git a/src/p_tick.c b/src/p_tick.c index 444b68d2f..c19f901e3 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -217,6 +217,7 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker) thlist[n].prev = thinker; thinker->references = 0; // killough 11/98: init reference counter to 0 + thinker->cachable = n == THINK_MOBJ; #ifdef PARANOIA thinker->debug_mobjtype = MT_NULL; @@ -319,7 +320,16 @@ void P_RemoveThinkerDelayed(thinker_t *thinker) (next->prev = currentthinker = thinker->prev)->next = next; R_DestroyLevelInterpolators(thinker); - Z_Free(thinker); + if (thinker->cachable) + { + // put cachable thinkers in the mobj cache, so we can avoid allocations + ((mobj_t *)thinker)->hnext = mobjcache; + mobjcache = (mobj_t *)thinker; + } + else + { + Z_Free(thinker); + } } // From b10b9c35ed3af0a72c0547e413a8abca49cc9776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 6 Nov 2023 19:09:43 +0100 Subject: [PATCH 27/85] Add support for multiple admin passwords --- src/netcode/d_clisrv.c | 27 ++++++++++++++++----------- src/netcode/d_clisrv.h | 4 ++-- src/netcode/d_netcmd.c | 35 +++++++++++++++++++++++++++++++---- src/netcode/d_netcmd.h | 1 + 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 7804b068f..71b87d28c 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -90,8 +90,8 @@ INT16 consistancy[BACKUPTICS]; // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks boolean hu_stopped = false; -UINT8 adminpassmd5[16]; -boolean adminpasswordset = false; +UINT8 (*adminpassmd5)[16]; +UINT32 adminpasscount = 0; tic_t neededtic; SINT8 servernode = 0; // the number of the server node @@ -862,26 +862,31 @@ static void PT_Login(SINT8 node, INT32 netconsole) #ifndef NOMD5 UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ + UINT32 i; if (doomcom->datalength < 16)/* ignore partial sends */ return; - if (!adminpasswordset) + if (adminpasscount == 0) { CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); return; } - // Do the final pass to compare with the sent md5 - D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5); - - if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) + for (i = 0; i < adminpasscount; i++) { - CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); - COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately + // Do the final pass to compare with the sent md5 + D_MD5PasswordPass(adminpassmd5[i], 16, va("PNUM%02d", netconsole), &finalmd5); + + if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) + { + CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); + COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately + return; + } } - else - CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); + + CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); #else (void)netconsole; #endif diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index db9a780cd..53ebfb15b 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -127,8 +127,8 @@ tic_t GetLag(INT32 node); void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest); -extern UINT8 adminpassmd5[16]; -extern boolean adminpasswordset; +extern UINT8 (*adminpassmd5)[16]; +extern UINT32 adminpasscount; extern boolean hu_stopped; diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 9b87e8cfe..bfacc26fa 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -150,6 +150,7 @@ static void Command_Clearscores_f(void); // Remote Administration static void Command_Changepassword_f(void); +static void Command_Clearpassword_f(void); static void Command_Login_f(void); static void Got_Verification(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum); @@ -468,6 +469,7 @@ void D_RegisterServerCommands(void) // Remote Administration COM_AddCommand("password", Command_Changepassword_f, COM_LUA); + COM_AddCommand("clearpassword", Command_Clearpassword_f, COM_LUA); COM_AddCommand("login", Command_Login_f, COM_LUA); // useful in dedicated to kick off remote admin COM_AddCommand("promote", Command_Verify_f, COM_LUA); RegisterNetXCmd(XD_VERIFIED, Got_Verification); @@ -2841,8 +2843,15 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) void D_SetPassword(const char *pw) { - D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5); - adminpasswordset = true; + adminpassmd5 = Z_Realloc(adminpassmd5, sizeof(*adminpassmd5) * ++adminpasscount, PU_STATIC, NULL); + D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5[adminpasscount-1]); +} + +void D_ClearPassword(void) +{ + Z_Free(adminpassmd5); + adminpassmd5 = NULL; + adminpasscount = 0; } // Remote Administration @@ -2860,12 +2869,30 @@ static void Command_Changepassword_f(void) if (COM_Argc() != 2) { - CONS_Printf(M_GetText("password : change remote admin password\n")); + CONS_Printf(M_GetText("password : add remote admin password\n")); return; } D_SetPassword(COM_Argv(1)); - CONS_Printf(M_GetText("Password set.\n")); + CONS_Printf(M_GetText("Password added.\n")); +#endif +} + +// Remote Administration +static void Command_Clearpassword_f(void) +{ +#ifdef NOMD5 + // If we have no MD5 support then completely disable XD_LOGIN responses for security. + CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n"); +#else + if (client) // cannot change remotely + { + CONS_Printf(M_GetText("Only the server can use this.\n")); + return; + } + + D_ClearPassword(); + CONS_Printf(M_GetText("Passwords cleared.\n")); #endif } diff --git a/src/netcode/d_netcmd.h b/src/netcode/d_netcmd.h index 4849079d0..0f2a1f92b 100644 --- a/src/netcode/d_netcmd.h +++ b/src/netcode/d_netcmd.h @@ -209,6 +209,7 @@ void ClearAdminPlayers(void); void RemoveAdminPlayer(INT32 playernum); void ItemFinder_OnChange(void); void D_SetPassword(const char *pw); +void D_ClearPassword(void); // used for the player setup menu UINT8 CanChangeSkin(INT32 playernum); From c6cd14c1565dff1d10d92c41032a7c074c3bf403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 11 Nov 2023 14:12:51 +0100 Subject: [PATCH 28/85] Allow specifying interface for IPv6 addresses --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 629f53d24..c0e8df02c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -11947,7 +11947,7 @@ static void M_HandleConnectIP(INT32 choice) // Rudimentary number and period enforcing - also allows letters so hostnames can be used instead // and square brackets for RFC 2732 IPv6 addresses if ((choice >= '-' && choice <= ':') || - (choice == '[' || choice == ']') || + (choice == '[' || choice == ']' || choice == '%') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z')) { From 2450a0df70c80629a399ebd9f79e3e3bd838a9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 11 Nov 2023 19:09:39 +0100 Subject: [PATCH 29/85] Do not send disconnected players' statuses to the MS --- src/netcode/d_clisrv.c | 11 +++++++++++ src/netcode/d_clisrv.h | 1 + src/netcode/server_connection.c | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 7804b068f..ac0b42d49 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1618,6 +1618,17 @@ INT32 D_NumPlayers(void) return num; } +/** Returns the number of nodes on the server. + */ +INT32 D_NumNodes(void) +{ + INT32 num = 0; + for (INT32 ix = 0; ix < MAXNETNODES; ix++) + if (netnodes[ix].ingame) + num++; + return num; +} + /** Similar to the above, but counts only bots. * Purpose is to remove bots from both the player count and the * max player count on the server view diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index db9a780cd..092878421 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -121,6 +121,7 @@ extern char motd[254], server_context[8]; extern UINT8 playernode[MAXPLAYERS]; INT32 D_NumPlayers(void); +INT32 D_NumNodes(void); INT32 D_NumBots(void); tic_t GetLag(INT32 node); diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index 2164f411a..258d4cce4 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -109,7 +109,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); // Exclude bots from both counts - netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumPlayers() - D_NumBots()); + netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumNodes(); netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots()); netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); @@ -164,7 +164,7 @@ static void SV_SendPlayerInfo(INT32 node) for (UINT8 i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i]) + if (!netnodes[playernode[i]].ingame) { netbuffer->u.playerinfo[i].num = 255; // This slot is empty. continue; From 6a6b65ddc45cc0c7d2964e7cd76c7214a5d23131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 16 Nov 2023 21:03:06 +0100 Subject: [PATCH 30/85] Optimize Z position functions on sloped sectors --- src/p_mobj.c | 8 ++++---- src/r_main.c | 28 ++++++++++++++++++++++++++++ src/r_main.h | 1 + 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7a5aaf424..2f9702d1c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1109,7 +1109,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point @@ -1186,7 +1186,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point @@ -1264,7 +1264,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point @@ -1341,7 +1341,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point diff --git a/src/r_main.c b/src/r_main.c index 6c7bedbf1..aab6ed620 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1027,6 +1027,34 @@ void R_Init(void) framecount = 0; } +// +// R_IsPointInSector +// +boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y) +{ + size_t i; + line_t *closest = NULL; + fixed_t closestdist = 0x7fffffff; + + for (i = 0; i < sector->linecount; i++) + { + vertex_t v; + fixed_t dist; + + // find the line closest to the point we're looking for. + P_ClosestPointOnLine(x, y, sector->lines[i], &v); + dist = R_PointToDist2(0, 0, v.x - x, v.y - y); + if (dist < closestdist) + { + closest = sector->lines[i]; + closestdist = dist; + } + } + + // if the side of the closest line is in this sector, we're inside of it. + return P_PointOnLineSide(x, y, closest) == 0 ? closest->frontsector == sector : closest->backsector == sector; +} + // // R_PointInSubsector // diff --git a/src/r_main.h b/src/r_main.h index a6fb42ba2..02c640b51 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -79,6 +79,7 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y); fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); fixed_t R_ScaleFromGlobalAngle(angle_t visangle); +boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y); subsector_t *R_PointInSubsector(fixed_t x, fixed_t y); subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y); From db9b26c8764ca157510821350ee0fbb9d52807d2 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Thu, 16 Nov 2023 20:36:08 +0000 Subject: [PATCH 31/85] Use INT32_MAX --- src/r_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index aab6ed620..06454646b 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1034,7 +1034,7 @@ boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y) { size_t i; line_t *closest = NULL; - fixed_t closestdist = 0x7fffffff; + fixed_t closestdist = INT32_MAX; for (i = 0; i < sector->linecount; i++) { From 59aa82a83cf5c546a64de2fe6f3eace3c03f38ea Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 23 Nov 2023 18:21:29 -0300 Subject: [PATCH 32/85] Correct texture scaling, part 1 --- src/r_segs.c | 242 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 165 insertions(+), 77 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 4c5c0dee9..18b5ba550 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -42,25 +42,24 @@ angle_t rw_normalangle; // angle to line origin angle_t rw_angle1; fixed_t rw_distance; -// Horizontal scaling hack shenanigans. -fixed_t rw_distance_scalex_top; -fixed_t rw_distance_scalex_mid; -fixed_t rw_distance_scalex_bot; // // regular wall // static INT32 rw_x, rw_stopx; static angle_t rw_centerangle; -static fixed_t rw_offset; +static fixed_t rw_offset, rw_offsetx; static fixed_t rw_offset_top, rw_offset_mid, rw_offset_bot; -static fixed_t rw_offset2; // for splats static fixed_t rw_scale, rw_scalestep; static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation +static fixed_t rw_midtexturescalex, rw_midtexturescaley; +static fixed_t rw_toptexturescalex, rw_toptexturescaley; +static fixed_t rw_bottomtexturescalex, rw_bottomtexturescaley; +static fixed_t rw_invmidtexturescalex, rw_invtoptexturescalex, rw_invbottomtexturescalex; // Lactozilla: 3D floor clipping static boolean rw_floormarked = false; @@ -73,7 +72,6 @@ static fixed_t *rw_bsilheight = NULL; static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; -static fixed_t topxscale, topyscale, midxscale, midyscale, botxscale, botyscale; static lighttable_t **walllights; static fixed_t *maskedtexturecol; @@ -1055,10 +1053,11 @@ static void R_RenderSegLoop (void) INT32 mid; fixed_t texturecolumn = 0; - fixed_t texturecolumn_top = 0; - fixed_t texturecolumn_mid = 0; - fixed_t texturecolumn_bot = 0; + fixed_t toptexturecolumn = 0; + fixed_t bottomtexturecolumn = 0; fixed_t oldtexturecolumn = -1; + fixed_t oldtexturecolumn_top = -1; + fixed_t oldtexturecolumn_bottom = -1; INT32 top; INT32 bottom; INT32 i; @@ -1225,20 +1224,10 @@ static void R_RenderSegLoop (void) //SoM: Calculate offsets for Thick fake floors. // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; - texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); - texturecolumn_top = (rw_offset_top - FixedMul(FINETANGENT(angle),rw_distance_scalex_top))>>FRACBITS; - texturecolumn_mid = (rw_offset_mid - FixedMul(FINETANGENT(angle),rw_distance_scalex_mid))>>FRACBITS; - texturecolumn_bot = (rw_offset_bot - FixedMul(FINETANGENT(angle),rw_distance_scalex_bot))>>FRACBITS; - if (oldtexturecolumn != -1) { - rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); - rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); - rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); - rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); - } - oldtexturecolumn = texturecolumn; + fixed_t distance = FixedMul(FINETANGENT(angle), rw_distance); - INT32 itexturecolumn = texturecolumn >> FRACBITS; + texturecolumn = FixedDiv(rw_offset - distance, rw_invmidtexturescalex); // texturecolumn and lighting are independent of wall tiers if (segtextured) @@ -1251,7 +1240,6 @@ static void R_RenderSegLoop (void) dc_colormap = walllights[pindex]; dc_x = rw_x; - dc_iscale = 0xffffffffu / (unsigned)rw_scale; if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -1301,11 +1289,13 @@ static void R_RenderSegLoop (void) // single sided line if (yl <= yh && yh >= 0 && yl < viewheight) { + fixed_t offset = texturecolumn + rw_offsetx; + dc_yl = yl; dc_yh = yh; - dc_texturemid = FixedMul(rw_midtexturemid, midyscale); - dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, midyscale); - dc_source = R_GetColumn(midtexture, itexturecolumn + texturecolumn_mid); + dc_texturemid = rw_midtexturemid; + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_midtexturescaley); + dc_source = R_GetColumn(midtexture, offset >> FRACBITS); dc_texheight = textureheight[midtexture]>>FRACBITS; //profile stuff --------------------------------------------------------- @@ -1354,6 +1344,8 @@ static void R_RenderSegLoop (void) if (mid >= floorclip[rw_x]) mid = floorclip[rw_x]-1; + toptexturecolumn = FixedDiv(rw_offset - distance, rw_invtoptexturescalex); + if (mid >= yl) // back ceiling lower than front ceiling ? { if (yl >= viewheight) // entirely off bottom of screen @@ -1363,11 +1355,16 @@ static void R_RenderSegLoop (void) } else if (mid >= 0) // safe to draw top texture { + fixed_t offset = rw_offset_top; + if (rw_toptexturescalex < 0) + offset = -offset; + offset = toptexturecolumn + offset; + dc_yl = yl; dc_yh = mid; - dc_texturemid = FixedMul(rw_toptexturemid, topyscale); - dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, topyscale); - dc_source = R_GetColumn(toptexture, itexturecolumn + texturecolumn_top); + dc_texturemid = rw_toptexturemid; + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_toptexturescaley); + dc_source = R_GetColumn(toptexture, toptexturecolumn >> FRACBITS); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1377,6 +1374,10 @@ static void R_RenderSegLoop (void) } else if (!rw_ceilingmarked) ceilingclip[rw_x] = topclip; + + if (oldtexturecolumn_top != -1) + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-toptexturecolumn); + oldtexturecolumn_top = toptexturecolumn; } else if (markceiling && (!rw_ceilingmarked)) // no top wall ceilingclip[rw_x] = topclip; @@ -1391,6 +1392,8 @@ static void R_RenderSegLoop (void) if (mid <= ceilingclip[rw_x]) mid = ceilingclip[rw_x]+1; + bottomtexturecolumn = FixedDiv(rw_offset - distance, rw_invbottomtexturescalex); + if (mid <= yh) // back floor higher than front floor ? { if (yh < 0) // entirely off top of screen @@ -1400,11 +1403,16 @@ static void R_RenderSegLoop (void) } else if (mid < viewheight) // safe to draw bottom texture { + fixed_t offset = rw_offset_bot; + if (rw_bottomtexturescalex < 0) + offset = -offset; + offset = bottomtexturecolumn + offset; + dc_yl = mid; dc_yh = yh; - dc_texturemid = FixedMul(rw_bottomtexturemid, botyscale); - dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, botyscale); - dc_source = R_GetColumn(bottomtexture, itexturecolumn + texturecolumn_bot); + dc_texturemid = rw_bottomtexturemid; + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_bottomtexturescaley); + dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); floorclip[rw_x] = (INT16)mid; @@ -1414,6 +1422,10 @@ static void R_RenderSegLoop (void) } else if (!rw_floormarked) floorclip[rw_x] = bottomclip; + + if (oldtexturecolumn_bottom != -1) + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-bottomtexturecolumn); + oldtexturecolumn_bottom = bottomtexturecolumn; } else if (markfloor && (!rw_floormarked)) // no bottom wall floorclip[rw_x] = bottomclip; @@ -1423,7 +1435,7 @@ static void R_RenderSegLoop (void) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)texturecolumn_mid; + maskedtexturecol[rw_x] = texturecolumn >> FRACBITS; if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? @@ -1442,6 +1454,17 @@ static void R_RenderSegLoop (void) } } + if (midtexture || maskedtextureheight) + { + if (oldtexturecolumn != -1) + { + rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); + rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); + } + + oldtexturecolumn = texturecolumn; + } + for (i = 0; i < numffloors; i++) { if (curline->polyseg && (ffloor[i].polyobj != curline->polyseg)) @@ -1765,32 +1788,67 @@ void R_StoreWallRange(INT32 start, INT32 stop) ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); } + rw_midtexturescalex = sidedef->scalex_mid; + rw_midtexturescaley = sidedef->scaley_mid; + rw_invmidtexturescalex = FixedDiv(FRACUNIT, rw_midtexturescalex); + if (!backsector) { - fixed_t texheight; - // single sided line midtexture = R_GetTextureNum(sidedef->midtexture); - texheight = textureheight[midtexture]; + // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; - if (linedef->flags & ML_NOSKEW) { - if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = frontsector->floorheight + texheight - viewz; - else - rw_midtexturemid = frontsector->ceilingheight - viewz; - } - else if (linedef->flags & ML_DONTPEGBOTTOM) + + fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid; + fixed_t texheight = textureheight[midtexture]; + + if (rw_midtexturescaley > 0) { - rw_midtexturemid = worldbottom + texheight; - rw_midtextureslide = floorfrontslide; + if (linedef->flags & ML_NOSKEW) + { + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight; + else + rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley); + } + else if (linedef->flags & ML_DONTPEGBOTTOM) + { + rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight; + rw_midtextureslide = FixedMul(floorfrontslide, rw_midtexturescaley); + } + else + { + // top of texture at top + rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley); + rw_midtextureslide = FixedMul(ceilingfrontslide, rw_midtexturescaley); + } } else { - // top of texture at top - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; + // Upside down + rowoffset = -rowoffset; + + if (linedef->flags & ML_NOSKEW) + { + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley); + else + rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley) + texheight; + } + else if (linedef->flags & ML_DONTPEGBOTTOM) + { + rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley); + rw_midtextureslide = FixedMul(floorfrontslide, rw_midtexturescaley); + } + else + { + // top of texture at top + rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight; + rw_midtextureslide = FixedMul(ceilingfrontslide, rw_midtexturescaley); + } } - rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid; + + rw_midtexturemid += rowoffset; ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; @@ -1976,16 +2034,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } + fixed_t toprowoffset = sidedef->rowoffset + sidedef->offsety_top; + fixed_t botrowoffset = sidedef->rowoffset + sidedef->offsety_bot; + // check TOP TEXTURE if (!bothceilingssky // never draw the top texture if on && (worldhigh < worldtop || worldhighslope < worldtopslope)) { - fixed_t texheight; - // top texture toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - if (!(linedef->flags & ML_SKEWTD)) { // Ignore slopes for lower/upper textures unless flag is checked + rw_toptexturescalex = sidedef->scalex_top; + rw_toptexturescaley = sidedef->scaley_top; + + rw_invtoptexturescalex = FixedDiv(FRACUNIT, rw_toptexturescalex); + + if (rw_toptexturescaley < 0) + toprowoffset = -toprowoffset; + + fixed_t texheight = textureheight[toptexture]; + + // Ignore slopes for lower/upper textures unless flag is checked + if (!(linedef->flags & ML_SKEWTD)) + { if (linedef->flags & ML_DONTPEGTOP) rw_toptexturemid = frontsector->ceilingheight - viewz; else @@ -2002,7 +2072,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_toptexturemid = worldhigh + texheight; rw_toptextureslide = ceilingbackslide; } + + rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley); + rw_toptextureslide = FixedMul(rw_toptextureslide, rw_toptexturescaley); } + // check BOTTOM TEXTURE if (!bothfloorssky // never draw the bottom texture if on && (worldlow > worldbottom || worldlowslope > worldbottomslope)) // Only if VISIBLE!!! @@ -2010,7 +2084,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) // bottom texture bottomtexture = R_GetTextureNum(sidedef->bottomtexture); - if (!(linedef->flags & ML_SKEWTD)) { // Ignore slopes for lower/upper textures unless flag is checked + rw_bottomtexturescalex = sidedef->scalex_bot; + rw_bottomtexturescaley = sidedef->scaley_bot; + + rw_invbottomtexturescalex = FixedDiv(FRACUNIT, rw_bottomtexturescalex); + + if (rw_bottomtexturescaley < 0) + botrowoffset = -botrowoffset; + + // Ignore slopes for lower/upper textures unless flag is checked + if (!(linedef->flags & ML_SKEWTD)) + { if (linedef->flags & ML_DONTPEGBOTTOM) rw_bottomtexturemid = frontsector->floorheight - viewz; else @@ -2023,14 +2107,19 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_bottomtexturemid = worldbottom; rw_bottomtextureslide = floorfrontslide; } - else { // top of texture at top + else + { + // top of texture at top rw_bottomtexturemid = worldlow; rw_bottomtextureslide = floorbackslide; } + + rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley); + rw_bottomtextureslide = FixedMul(rw_bottomtextureslide, rw_bottomtexturescaley); } - rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top; - rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot; + rw_toptexturemid += toprowoffset; + rw_bottomtexturemid += botrowoffset; R_AllocTextureColumnTables(rw_stopx - start); @@ -2241,7 +2330,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) if (curline->polyseg) - { // use REAL front and back floors please, so midtexture rendering isn't mucked up + { + // use REAL front and back floors please, so midtexture rendering isn't mucked up rw_midtextureslide = rw_midtexturebackslide = 0; if (linedef->flags & ML_MIDPEG) rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; @@ -2252,7 +2342,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // Set midtexture starting height if (linedef->flags & ML_NOSKEW) - { // Ignore slopes when texturing + { + // Ignore slopes when texturing rw_midtextureslide = rw_midtexturebackslide = 0; if (linedef->flags & ML_MIDPEG) rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; @@ -2275,6 +2366,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_midtexturebackslide = ceilingbackslide; } } + + rw_midtexturemid = FixedMul(rw_midtexturemid, rw_midtexturescaley); + rw_midtextureback = FixedMul(rw_midtextureback, rw_midtexturescaley); + rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid; rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid; @@ -2311,26 +2406,19 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rw_normalangle-rw_angle1 < ANGLE_180) rw_offset = -rw_offset; - /// don't use texture offset for splats - rw_offset2 = rw_offset + curline->offset; - - // Per-texture scaling, offsetting. - topxscale = sidedef->scalex_top; - midxscale = sidedef->scalex_mid; - botxscale = sidedef->scalex_bot; - topyscale = sidedef->scaley_top; - midyscale = sidedef->scaley_mid; - botyscale = sidedef->scaley_bot; - rw_offset_top = FixedMul(rw_offset + curline->offset + sidedef->textureoffset + sidedef->offsetx_top, topxscale); - rw_offset_mid = FixedMul(rw_offset + curline->offset + sidedef->textureoffset + sidedef->offsetx_mid, midxscale); - rw_offset_bot = FixedMul(rw_offset + curline->offset + sidedef->textureoffset + sidedef->offsetx_bot, botxscale); - rw_distance_scalex_top = FixedMul(rw_distance, topxscale); - rw_distance_scalex_mid = FixedMul(rw_distance, midxscale); - rw_distance_scalex_bot = FixedMul(rw_distance, botxscale); - - rw_offset += sidedef->textureoffset + curline->offset; + rw_offset += curline->offset; rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; + rw_offsetx = sidedef->textureoffset; + + rw_offset_top = rw_offsetx + sidedef->offsetx_top; + rw_offset_mid = rw_offsetx + sidedef->offsetx_mid; + rw_offset_bot = rw_offsetx + sidedef->offsetx_bot; + + rw_offsetx = rw_offset_mid; + if (rw_midtexturescalex < 0) + rw_offsetx = -rw_offsetx; + // calculate light table // use different light tables // for horizontal / vertical / diagonal From 10537deacfa811923479245211c0e91ebd9a3126 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 23 Nov 2023 19:16:03 -0300 Subject: [PATCH 33/85] Correct texture scaling, part 2 --- src/r_defs.h | 1 + src/r_segs.c | 106 +++++++++++++++++++++++++++++---------------------- 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 83d9825ca..06a16de9e 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -761,6 +761,7 @@ typedef struct drawseg_s INT16 *sprtopclip; INT16 *sprbottomclip; fixed_t *maskedtexturecol; + fixed_t *invscale; struct visplane_s *ffloorplanes[MAXFFLOORS]; INT32 numffloorplanes; diff --git a/src/r_segs.c b/src/r_segs.c index 18b5ba550..f3c380b91 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -74,8 +74,9 @@ static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; -static fixed_t *maskedtexturecol; +static fixed_t *maskedtexturecol = NULL; static fixed_t *maskedtextureheight = NULL; +static fixed_t *invscale = NULL; //SoM: 3/23/2000: Use boom opening limit removal static size_t numopenings; @@ -165,7 +166,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) frontsector = curline->frontsector; backsector = curline->backsector; - texnum = R_GetTextureNum(curline->sidedef->midtexture); + sidedef = curline->sidedef; + texnum = R_GetTextureNum(sidedef->midtexture); windowbottom = windowtop = sprbotscreen = INT32_MAX; ldef = curline->linedef; @@ -203,9 +205,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) colfunc = colfuncs[COLDRAWFUNC_FUZZY]; } + fixed_t wall_scaley = sidedef->scaley_mid; + fixed_t scalestep = FixedDiv(ds->scalestep, wall_scaley); + fixed_t scale1 = FixedDiv(ds->scale1, wall_scaley); + range = max(ds->x2-ds->x1, 1); - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + rw_scalestep = scalestep; + spryscale = scale1 + (x1 - ds->x1)*rw_scalestep; // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be @@ -316,8 +322,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else back = backsector; - if (ds->curline->sidedef->repeatcnt) - repeats = 1 + ds->curline->sidedef->repeatcnt; + if (sidedef->repeatcnt) + repeats = 1 + sidedef->repeatcnt; else if (ldef->flags & ML_WRAPMIDTEX) { fixed_t high, low; @@ -343,15 +349,14 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { if (times > 0) { - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; - if (dc_numlights) - { // reset all lights to their starting heights - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height = rlight->startheight; - } + rw_scalestep = scalestep; + spryscale = scale1 + (x1 - ds->x1)*rw_scalestep; + + // reset all lights to their starting heights + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height = rlight->startheight; } } @@ -393,8 +398,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) sprbotscreen = INT32_MAX; sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; + realbot = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; + dc_iscale = FixedMul(ds->invscale[dc_x], wall_scaley); + + windowbottom = realbot; // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); @@ -469,7 +476,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; + dc_iscale = FixedMul(ds->invscale[dc_x], wall_scaley); // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); @@ -1431,27 +1438,15 @@ static void R_RenderSegLoop (void) floorclip[rw_x] = bottomclip; } - if (maskedtexture || numthicksides) - { - // save texturecol - // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = texturecolumn >> FRACBITS; + if (maskedtexturecol) + maskedtexturecol[rw_x] = texturecolumn; - if (maskedtextureheight != NULL) { - maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? - max(rw_midtexturemid, rw_midtextureback) : - min(rw_midtexturemid, rw_midtextureback); - } - } - - if (dc_numlights) + if (maskedtextureheight) { - for (i = 0; i < dc_numlights; i++) - { - dc_lightlist[i].height += dc_lightlist[i].heightstep; - if (dc_lightlist[i].flags & FOF_CUTSOLIDS) - dc_lightlist[i].botheight += dc_lightlist[i].botheightstep; - } + if (curline->linedef->flags & ML_MIDPEG) + maskedtextureheight[rw_x] = max(rw_midtexturemid, rw_midtextureback); + else + maskedtextureheight[rw_x] = min(rw_midtexturemid, rw_midtextureback); } if (midtexture || maskedtextureheight) @@ -1465,6 +1460,19 @@ static void R_RenderSegLoop (void) oldtexturecolumn = texturecolumn; } + if (invscale) + invscale[rw_x] = 0xffffffffu / (unsigned)rw_scale; + + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + dc_lightlist[i].height += dc_lightlist[i].heightstep; + if (dc_lightlist[i].flags & FOF_CUTSOLIDS) + dc_lightlist[i].botheight += dc_lightlist[i].botheightstep; + } + } + for (i = 0; i < numffloors; i++) { if (curline->polyseg && (ffloor[i].polyobj != curline->polyseg)) @@ -1569,6 +1577,8 @@ static void R_AllocTextureColumnTables(size_t range) ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable; if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast) ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable; + if (ds->invscale + ds->x1 >= oldtable && ds->invscale + ds->x1 <= oldlast) + ds->invscale = (ds->invscale - oldtable) + texturecolumntable; } } @@ -1592,7 +1602,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; static size_t maxdrawsegs = 0; + maskedtexturecol = NULL; maskedtextureheight = NULL; + invscale = NULL; + //initialize segleft and segright memset(&segleft, 0x00, sizeof(segleft)); memset(&segright, 0x00, sizeof(segright)); @@ -1749,6 +1762,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->maskedtexturecol = NULL; ds_p->numthicksides = numthicksides = 0; ds_p->thicksidecol = NULL; + ds_p->invscale = NULL; ds_p->tsilheight = 0; numbackffloors = 0; @@ -2134,10 +2148,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Used for height comparisons and etc across FOFs and slopes fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; - //markceiling = markfloor = true; maskedtexture = true; - ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x; + ds_p->thicksidecol = curtexturecolumntable - rw_x; curtexturecolumntable += rw_stopx - rw_x; lowcut = max(worldbottom, worldlow) + viewz; @@ -2319,13 +2332,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) { // masked midtexture - if (!ds_p->thicksidecol) - { - ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; - curtexturecolumntable += rw_stopx - rw_x; - } - else - ds_p->maskedtexturecol = ds_p->thicksidecol; + ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) @@ -2438,6 +2446,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) walllights = scalelight[lightnum]; } + if (maskedtexture) + { + ds_p->invscale = invscale = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; + } + // if a floor / ceiling plane is on the wrong side // of the view plane, it is definitely invisible // and doesn't need to be marked. From 2f20f21eb6dd6ba80983bc9b53edb15f099dcceb Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 23 Nov 2023 20:03:23 -0300 Subject: [PATCH 34/85] Correct texture scaling, part 3 --- src/r_defs.h | 2 + src/r_segs.c | 105 ++++++++++++++++++++++++++------------------------- 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 06a16de9e..82d752260 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -757,6 +757,8 @@ typedef struct drawseg_s fixed_t bsilheight; // do not clip sprites above this fixed_t tsilheight; // do not clip sprites below this + fixed_t offsetx; + // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. INT16 *sprtopclip; INT16 *sprbottomclip; diff --git a/src/r_segs.c b/src/r_segs.c index f3c380b91..ec3877670 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -76,6 +76,7 @@ static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; static fixed_t *maskedtexturecol = NULL; static fixed_t *maskedtextureheight = NULL; +static fixed_t *thicksidecol = NULL; static fixed_t *invscale = NULL; //SoM: 3/23/2000: Use boom opening limit removal @@ -535,7 +536,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 i, p; fixed_t bottombounds = viewheight << FRACBITS; fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; - fixed_t offsetvalue = 0; + fixed_t offsetvalue; lightlist_t *light; r_lightlist_t *rlight; INT32 range; @@ -544,11 +545,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // NOTE: INT64 instead of fixed_t because overflow concerns INT64 top_frac, top_step, bottom_frac, bottom_step; // skew FOF walls with slopes? - boolean slopeskew = false; fixed_t ffloortextureslide = 0; INT32 oldx = -1; fixed_t left_top, left_bottom; // needed here for slope skewing pslope_t *skewslope = NULL; + boolean do_texture_skew; + UINT32 lineflags; + fixed_t wall_scalex, wall_scaley; void (*colfunc_2s) (column_t *); @@ -560,7 +563,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) curline = ds->curline; backsector = pfloor->target; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + sidedef = &sides[pfloor->master->sidenum[0]]; colfunc = colfuncs[BASEDRAWFUNC]; @@ -568,8 +571,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { size_t linenum = curline->linedef-backsector->lines[0]; newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + sidedef = &sides[newline->sidenum[0]]; + lineflags = newline->flags; } + else + lineflags = pfloor->master->flags; + + texnum = R_GetTextureNum(sidedef->midtexture); if (pfloor->fofflags & FOF_TRANSLUCENT) { @@ -721,7 +729,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) walllights = scalelight[lightnum]; } - maskedtexturecol = ds->thicksidecol; + wall_scalex = FixedDiv(FRACUNIT, sidedef->scalex_mid); + wall_scaley = sidedef->scaley_mid; + + thicksidecol = ds->thicksidecol; + + for (INT32 x = x1; x <= x2; x++) + thicksidecol[x] = FixedDiv(thicksidecol[x], wall_scalex) + ds->offsetx; mfloorclip = ds->sprbottomclip; mceilingclip = ds->sprtopclip; @@ -731,51 +745,29 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; + do_texture_skew = lineflags & ML_SKEWTD; skewslope = *pfloor->t_slope; // skew using top slope by default - if (newline) - { - if (newline->flags & ML_SKEWTD) - slopeskew = true; - } - else if (pfloor->master->flags & ML_SKEWTD) - slopeskew = true; - if (slopeskew) - dc_texturemid = left_top; + if (do_texture_skew) + dc_texturemid = FixedMul(left_top, wall_scaley); else - dc_texturemid = *pfloor->topheight - viewz; + dc_texturemid = FixedMul(*pfloor->topheight - viewz, wall_scaley); - if (newline) + offsetvalue = sidedef->rowoffset + sidedef->offsety_mid; + + if (lineflags & ML_DONTPEGBOTTOM) { - offsetvalue = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid; - if (newline->flags & ML_DONTPEGBOTTOM) - { - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = left_bottom; - else - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } - } - else - { - offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset + sides[pfloor->master->sidenum[0]].offsety_mid; - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = left_bottom; - else - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } + skewslope = *pfloor->b_slope; // skew using bottom slope + if (do_texture_skew) + dc_texturemid = FixedMul(left_bottom, wall_scaley); + else + offsetvalue -= FixedMul(*pfloor->topheight - *pfloor->bottomheight, wall_scaley); } - if (slopeskew) + if (do_texture_skew && skewslope) { angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (skewslope) - ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); } dc_texturemid += offsetvalue; @@ -829,7 +821,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (ffloortextureslide) { if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, maskedtexturecol[oldx]-maskedtexturecol[dc_x]); + dc_texturemid += FixedMul(ffloortextureslide, thicksidecol[oldx]-thicksidecol[dc_x]); oldx = dc_x; } @@ -862,10 +854,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; } - dc_iscale = 0xffffffffu / (unsigned)spryscale; + dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley); // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS)) - 3); // SoM: New code does not rely on R_DrawColumnShadowed_8 which // will (hopefully) put less strain on the stack. @@ -1439,7 +1431,10 @@ static void R_RenderSegLoop (void) } if (maskedtexturecol) - maskedtexturecol[rw_x] = texturecolumn; + maskedtexturecol[rw_x] = texturecolumn + rw_offsetx; + + if (thicksidecol) + thicksidecol[rw_x] = rw_offset - distance; if (maskedtextureheight) { @@ -1551,10 +1546,9 @@ static void R_AllocClippingTables(size_t range) static void R_AllocTextureColumnTables(size_t range) { size_t pos = curtexturecolumntable - texturecolumntable; + size_t need = range * 3; - // For both tables, we reserve exactly an amount of memory that's equivalent to - // how many columns the seg will take on the entire screen (think about it) - if (pos + range < texturecolumntablesize) + if (pos + need < texturecolumntablesize) return; fixed_t *oldtable = texturecolumntable; @@ -1563,7 +1557,7 @@ static void R_AllocTextureColumnTables(size_t range) if (texturecolumntablesize == 0) texturecolumntablesize = 16384; - texturecolumntablesize += range; + texturecolumntablesize += need; texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL); curtexturecolumntable = texturecolumntable + pos; @@ -1604,6 +1598,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) maskedtexturecol = NULL; maskedtextureheight = NULL; + thicksidecol = NULL; invscale = NULL; //initialize segleft and segright @@ -2135,9 +2130,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_toptexturemid += toprowoffset; rw_bottomtexturemid += botrowoffset; + // allocate space for masked texture tables R_AllocTextureColumnTables(rw_stopx - start); - // allocate space for masked texture tables if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) { ffloor_t *rover; @@ -2150,7 +2145,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) maskedtexture = true; - ds_p->thicksidecol = curtexturecolumntable - rw_x; + ds_p->thicksidecol = thicksidecol = curtexturecolumntable - rw_x; curtexturecolumntable += rw_stopx - rw_x; lowcut = max(worldbottom, worldlow) + viewz; @@ -2329,14 +2324,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->numthicksides = numthicksides = i; } + + // masked midtexture if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) { - // masked midtexture ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; curtexturecolumntable += rw_stopx - rw_x; maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) + maskedtexture = true; + if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up @@ -2427,6 +2425,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rw_midtexturescalex < 0) rw_offsetx = -rw_offsetx; + if (numthicksides) + ds_p->offsetx = rw_offsetx; + // calculate light table // use different light tables // for horizontal / vertical / diagonal From f3c98158b66760861b7f6badad019b203e92883a Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 23 Nov 2023 20:08:46 -0300 Subject: [PATCH 35/85] Fix top texture offsets --- src/r_segs.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index ec3877670..c7d77fa33 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -49,7 +49,7 @@ fixed_t rw_distance; static INT32 rw_x, rw_stopx; static angle_t rw_centerangle; static fixed_t rw_offset, rw_offsetx; -static fixed_t rw_offset_top, rw_offset_mid, rw_offset_bot; +static fixed_t rw_offset_top, rw_offset_mid, rw_offset_bottom; static fixed_t rw_scale, rw_scalestep; static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; @@ -1046,6 +1046,7 @@ UINT32 nombre = 100000; static void R_RenderSegLoop (void) { angle_t angle; + fixed_t textureoffset; size_t pindex; INT32 yl; INT32 yh; @@ -1223,10 +1224,8 @@ static void R_RenderSegLoop (void) //SoM: Calculate offsets for Thick fake floors. // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; - - fixed_t distance = FixedMul(FINETANGENT(angle), rw_distance); - - texturecolumn = FixedDiv(rw_offset - distance, rw_invmidtexturescalex); + textureoffset = rw_offset - FixedMul(FINETANGENT(angle), rw_distance); + texturecolumn = FixedDiv(textureoffset, rw_invmidtexturescalex); // texturecolumn and lighting are independent of wall tiers if (segtextured) @@ -1343,7 +1342,7 @@ static void R_RenderSegLoop (void) if (mid >= floorclip[rw_x]) mid = floorclip[rw_x]-1; - toptexturecolumn = FixedDiv(rw_offset - distance, rw_invtoptexturescalex); + toptexturecolumn = FixedDiv(textureoffset, rw_invtoptexturescalex); if (mid >= yl) // back ceiling lower than front ceiling ? { @@ -1363,7 +1362,7 @@ static void R_RenderSegLoop (void) dc_yh = mid; dc_texturemid = rw_toptexturemid; dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_toptexturescaley); - dc_source = R_GetColumn(toptexture, toptexturecolumn >> FRACBITS); + dc_source = R_GetColumn(toptexture, offset >> FRACBITS); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1391,7 +1390,7 @@ static void R_RenderSegLoop (void) if (mid <= ceilingclip[rw_x]) mid = ceilingclip[rw_x]+1; - bottomtexturecolumn = FixedDiv(rw_offset - distance, rw_invbottomtexturescalex); + bottomtexturecolumn = FixedDiv(textureoffset, rw_invbottomtexturescalex); if (mid <= yh) // back floor higher than front floor ? { @@ -1402,7 +1401,7 @@ static void R_RenderSegLoop (void) } else if (mid < viewheight) // safe to draw bottom texture { - fixed_t offset = rw_offset_bot; + fixed_t offset = rw_offset_bottom; if (rw_bottomtexturescalex < 0) offset = -offset; offset = bottomtexturecolumn + offset; @@ -1434,7 +1433,7 @@ static void R_RenderSegLoop (void) maskedtexturecol[rw_x] = texturecolumn + rw_offsetx; if (thicksidecol) - thicksidecol[rw_x] = rw_offset - distance; + thicksidecol[rw_x] = textureoffset; if (maskedtextureheight) { @@ -2388,6 +2387,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (segtextured) { + fixed_t sideoffset = sidedef->textureoffset; + offsetangle = rw_normalangle-rw_angle1; if (offsetangle > ANGLE_180) @@ -2415,11 +2416,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_offset += curline->offset; rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; - rw_offsetx = sidedef->textureoffset; - - rw_offset_top = rw_offsetx + sidedef->offsetx_top; - rw_offset_mid = rw_offsetx + sidedef->offsetx_mid; - rw_offset_bot = rw_offsetx + sidedef->offsetx_bot; + rw_offset_top = sideoffset + sidedef->offsetx_top; + rw_offset_mid = sideoffset + sidedef->offsetx_mid; + rw_offset_bottom = sideoffset + sidedef->offsetx_bot; rw_offsetx = rw_offset_mid; if (rw_midtexturescalex < 0) From ca4f7cc5082d2d9bd22a0dd8a32b891ccda1d7d3 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 23 Nov 2023 21:43:18 -0300 Subject: [PATCH 36/85] Correct OpenGL wall texture scaling --- src/hardware/hw_main.c | 173 ++++++++++++++++++++++------------------- src/p_setup.c | 4 +- 2 files changed, 93 insertions(+), 84 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0f36a51f7..2bb24497a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1149,6 +1149,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // check TOP TEXTURE if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) { + grTex = HWR_GetTexture(gl_toptexture); + xscale = FixedToFloat(gl_sidedef->scalex_top); + yscale = FixedToFloat(gl_sidedef->scaley_top); + fixed_t texheight = FixedDiv(textureheight[gl_toptexture], gl_sidedef->scaley_top); // PEGGING @@ -1159,41 +1163,39 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else texturevpeg = gl_backsector->ceilingheight + texheight - gl_frontsector->ceilingheight; + texturevpeg *= yscale; + texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway texturevpeg %= texheight; - grTex = HWR_GetTexture(gl_toptexture); - xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_top) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_top) * grTex->scaleY; - - wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_top) * xscale; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_top) * xscale; + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) { // Unskewed - wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * yscale; - wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * yscale; - wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * yscale; - wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * yscale; + wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * yscale * grTex->scaleY; + wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * yscale * grTex->scaleY; + wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * yscale * grTex->scaleY; + wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * yscale * grTex->scaleY; } else if (gl_linedef->flags & ML_DONTPEGTOP) { // Skewed by top - wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * yscale; - wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * yscale; + wallVerts[0].t = (texturevpeg + (worldtop - worldhigh) * yscale) * grTex->scaleY; + wallVerts[1].t = (texturevpeg + (worldtopslope - worldhighslope) * yscale) * grTex->scaleY; } else { // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * yscale; - wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * yscale; - wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + (worldtop - worldhigh) * yscale) * grTex->scaleY; + wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * yscale * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY; } // set top/bottom coords @@ -1213,6 +1215,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // check BOTTOM TEXTURE if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) { + grTex = HWR_GetTexture(gl_bottomtexture); + xscale = FixedToFloat(gl_sidedef->scalex_bot); + yscale = FixedToFloat(gl_sidedef->scaley_bot); + // PEGGING if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) texturevpeg = 0; @@ -1221,40 +1227,38 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight; + texturevpeg *= yscale; + texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bot; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bot); - grTex = HWR_GetTexture(gl_bottomtexture); - xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_bot) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_bot) * grTex->scaleY; - - wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * yscale; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_bot) * xscale; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_bot) * xscale; + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_backsector->floorheight - gl_frontsector->floorheight) * yscale) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_bot) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_bot) * grTex->scaleX; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) { // Unskewed - wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * yscale; - wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * yscale; - wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * yscale; - wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * yscale; + wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * yscale * grTex->scaleY; + wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * yscale * grTex->scaleY; + wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * yscale * grTex->scaleY; + wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * yscale * grTex->scaleY; } else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * yscale; - wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * yscale; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + (worldlow - worldbottom) * yscale) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * yscale * grTex->scaleY; } else { // Skewed by top - wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * yscale; - wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * yscale; + wallVerts[0].t = (texturevpeg + (worldlow - worldbottom) * yscale) * grTex->scaleY; + wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY; } // set top/bottom coords @@ -1311,6 +1315,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else repeats = 1; + grTex = HWR_GetTexture(gl_midtexture); + xscale = FixedToFloat(gl_sidedef->scalex_mid); + yscale = FixedToFloat(gl_sidedef->scaley_mid); + // SoM: a little note: popentop and popenbottom // record the limits the texture can be displayed in. // polytop and polybottom, are the ideal (i.e. unclipped) @@ -1338,19 +1346,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Find the wall's coordinates fixed_t midtexheight = texheight * repeats; + fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, gl_sidedef->scaley_mid); + // Texture is not skewed if (gl_linedef->flags & ML_NOSKEW) { // Peg it to the floor if (gl_linedef->flags & ML_MIDPEG) { - polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; + polybottom = max(front->floorheight, back->floorheight) + rowoffset; polytop = polybottom + midtexheight; } // Peg it to the ceiling else { - polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; + polytop = min(front->ceilingheight, back->ceilingheight) + rowoffset; polybottom = polytop - midtexheight; } @@ -1361,17 +1371,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Skew the texture, but peg it to the floor else if (gl_linedef->flags & ML_MIDPEG) { - polybottom = popenbottom + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; + polybottom = popenbottom + rowoffset; polytop = polybottom + midtexheight; - polybottomslope = popenbottomslope + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; + polybottomslope = popenbottomslope + rowoffset; polytopslope = polybottomslope + midtexheight; } // Skew it according to the ceiling's slope else { - polytop = popentop + gl_sidedef->rowoffset; + polytop = popentop + rowoffset; polybottom = polytop - midtexheight; - polytopslope = popentopslope + gl_sidedef->rowoffset; + polytopslope = popentopslope + rowoffset; polybottomslope = polytopslope - midtexheight; } @@ -1413,19 +1423,15 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpegslope = polytopslope - hS; } - grTex = HWR_GetTexture(gl_midtexture); - xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; - // Left side - wallVerts[3].t = texturevpeg * yscale; - wallVerts[0].t = (h - l + texturevpeg) * yscale; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; + wallVerts[3].t = texturevpeg * yscale * grTex->scaleY; + wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; // Right side - wallVerts[2].t = texturevpegslope * yscale; - wallVerts[1].t = (hS - lS + texturevpegslope) * yscale; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; + wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY; + wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; // set top/bottom coords // Take the texture peg into account, rather than changing the offsets past @@ -1483,38 +1489,40 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Single sided line... Deal only with the middletexture (if one exists) if (gl_midtexture && gl_linedef->special != HORIZONSPECIAL) // (Ignore horizon line for OGL) { + grTex = HWR_GetTexture(gl_midtexture); + xscale = FixedToFloat(gl_sidedef->scalex_mid); + yscale = FixedToFloat(gl_sidedef->scaley_mid); + fixed_t texturevpeg; // PEGGING if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW)) - texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; + texturevpeg = (gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight) * yscale; else if (gl_linedef->flags & ML_DONTPEGBOTTOM) - texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; + texturevpeg = (worldbottom + textureheight[gl_sidedef->midtexture] - worldtop) * yscale; else // top of texture at top - texturevpeg = gl_sidedef->rowoffset + gl_sidedef->offsety_mid; + texturevpeg = 0; - grTex = HWR_GetTexture(gl_midtexture); - xscale = FIXED_TO_FLOAT(gl_sidedef->scalex_mid) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(gl_sidedef->scaley_mid) * grTex->scaleY; + texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_mid; - wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * yscale; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; // Texture correction for slopes if (gl_linedef->flags & ML_NOSKEW) { - wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * yscale; - wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * yscale; - wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * yscale; - wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * yscale; + wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * yscale * grTex->scaleY; + wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * yscale * grTex->scaleY; + wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * yscale * grTex->scaleY; + wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * yscale * yscale; } else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { - wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * yscale; - wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * yscale; + wallVerts[3].t = wallVerts[0].t + ((worldbottom - worldtop) * yscale) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t + ((worldbottomslope - worldtopslope) * yscale) * grTex->scaleY; } else { - wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * yscale; - wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * yscale; + wallVerts[0].t = wallVerts[3].t - ((worldbottom - worldtop) * yscale) * grTex->scaleY; + wallVerts[1].t = wallVerts[2].t - ((worldbottomslope - worldtopslope) * yscale) * grTex->scaleY; } //Set textures properly on single sided walls that are sloped @@ -1661,36 +1669,37 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } grTex = HWR_GetTexture(texnum); - xscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scalex_mid) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scaley_mid) * grTex->scaleY; + xscale = FixedToFloat(sides[rover->master->sidenum[0]].scalex_mid); + yscale = FixedToFloat(sides[rover->master->sidenum[0]].scaley_mid); if (!slopeskew) // no skewing { if (attachtobottom) - texturevpeg -= *rover->topheight - *rover->bottomheight; - wallVerts[3].t = (*rover->topheight - h + texturevpeg) * yscale; - wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * yscale; - wallVerts[0].t = (*rover->topheight - l + texturevpeg) * yscale; - wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * yscale; + texturevpeg -= (*rover->topheight - *rover->bottomheight) * yscale; + + wallVerts[3].t = (((*rover->topheight - h) * yscale) + texturevpeg) * grTex->scaleY; + wallVerts[2].t = (((*rover->topheight - hS) * yscale) + texturevpeg) * grTex->scaleY; + wallVerts[0].t = (((*rover->topheight - l) * yscale) + texturevpeg) * grTex->scaleY; + wallVerts[1].t = (((*rover->topheight - lS) * yscale) + texturevpeg) * grTex->scaleY; } else { if (!attachtobottom) // skew by top { - wallVerts[3].t = wallVerts[2].t = texturevpeg * yscale; - wallVerts[0].t = (h - l + texturevpeg) * yscale; - wallVerts[1].t = (hS - lS + texturevpeg) * yscale; + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = (((h - l) * yscale) + texturevpeg) * grTex->scaleY; + wallVerts[1].t = (((hS - lS) * yscale) + texturevpeg) * grTex->scaleY; } else // skew by bottom { - wallVerts[0].t = wallVerts[1].t = texturevpeg * yscale; - wallVerts[3].t = wallVerts[0].t - (h - l) * yscale; - wallVerts[2].t = wallVerts[1].t - (hS - lS) * yscale; + wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; + wallVerts[3].t = wallVerts[0].t - ((h - l) * yscale) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t - ((hS - lS) * yscale) * grTex->scaleY; } } - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; } if (rover->fofflags & FOF_FOG) { diff --git a/src/p_setup.c b/src/p_setup.c index 1df91f70b..94dfb75ee 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3330,7 +3330,7 @@ static void P_LoadSegs(UINT8 *data) seg->length = P_SegLength(seg); #ifdef HWRENDER - seg->flength = (rendermode == render_opengl) ? P_SegLengthFloat(seg) : 0; + seg->flength = P_SegLengthFloat(seg); #endif seg->glseg = false; @@ -3562,7 +3562,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype } seg->length = P_SegLength(seg); #ifdef HWRENDER - seg->flength = (rendermode == render_opengl) ? P_SegLengthFloat(seg) : 0; + seg->flength = P_SegLengthFloat(seg); #endif } From 41cacd783b0245f0737e6bcdb70177d9b5009f71 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 23 Nov 2023 21:56:18 -0300 Subject: [PATCH 37/85] Serialize new side fields --- src/hardware/hw_main.c | 12 +- src/lua_maplib.c | 16 +-- src/p_saveg.c | 293 ++++++++++++++++++++++++++--------------- src/p_setup.c | 40 +++--- src/r_defs.h | 8 +- src/r_segs.c | 8 +- 6 files changed, 232 insertions(+), 145 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2bb24497a..8686a59e8 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1216,8 +1216,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) { grTex = HWR_GetTexture(gl_bottomtexture); - xscale = FixedToFloat(gl_sidedef->scalex_bot); - yscale = FixedToFloat(gl_sidedef->scaley_bot); + xscale = FixedToFloat(gl_sidedef->scalex_bottom); + yscale = FixedToFloat(gl_sidedef->scaley_bottom); // PEGGING if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) @@ -1229,15 +1229,15 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpeg *= yscale; - texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bot; + texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bot); + texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bottom); wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_backsector->floorheight - gl_frontsector->floorheight) * yscale) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_bot) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_bot) * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index c15892ab4..d81d28ba1 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1218,10 +1218,10 @@ static int side_get(lua_State *L) lua_pushfixed(L, side->offsety_mid); return 1; case side_offsetx_bot: - lua_pushfixed(L, side->offsetx_bot); + lua_pushfixed(L, side->offsetx_bottom); return 1; case side_offsety_bot: - lua_pushfixed(L, side->offsety_bot); + lua_pushfixed(L, side->offsety_bottom); return 1; case side_scalex_top: lua_pushfixed(L, side->scalex_top); @@ -1236,10 +1236,10 @@ static int side_get(lua_State *L) lua_pushfixed(L, side->scaley_mid); return 1; case side_scalex_bot: - lua_pushfixed(L, side->scalex_bot); + lua_pushfixed(L, side->scalex_bottom); return 1; case side_scaley_bot: - lua_pushfixed(L, side->scaley_bot); + lua_pushfixed(L, side->scaley_bottom); return 1; case side_toptexture: lua_pushinteger(L, side->toptexture); @@ -1324,10 +1324,10 @@ static int side_set(lua_State *L) side->offsety_mid = luaL_checkfixed(L, 3); break; case side_offsetx_bot: - side->offsetx_bot = luaL_checkfixed(L, 3); + side->offsetx_bottom = luaL_checkfixed(L, 3); break; case side_offsety_bot: - side->offsety_bot = luaL_checkfixed(L, 3); + side->offsety_bottom = luaL_checkfixed(L, 3); break; case side_scalex_top: side->scalex_top = luaL_checkfixed(L, 3); @@ -1342,10 +1342,10 @@ static int side_set(lua_State *L) side->scaley_mid = luaL_checkfixed(L, 3); break; case side_scalex_bot: - side->scalex_bot = luaL_checkfixed(L, 3); + side->scalex_bottom = luaL_checkfixed(L, 3); break; case side_scaley_bot: - side->scaley_bot = luaL_checkfixed(L, 3); + side->scaley_bottom = luaL_checkfixed(L, 3); break; case side_toptexture: side->toptexture = luaL_checkinteger(L, 3); diff --git a/src/p_saveg.c b/src/p_saveg.c index 4aa2318fd..4ab7aeccc 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -868,23 +868,42 @@ static void P_NetUnArchiveWaypoints(void) #define SD_TRIGGERER 0x04 #define SD_GRAVITY 0x08 -#define LD_FLAG 0x01 -#define LD_SPECIAL 0x02 -#define LD_CLLCOUNT 0x04 -#define LD_S1TEXOFF 0x08 -#define LD_S1TOPTEX 0x10 -#define LD_S1BOTTEX 0x20 -#define LD_S1MIDTEX 0x40 -#define LD_DIFF2 0x80 +#define LD_FLAG 0x01 +#define LD_SPECIAL 0x02 +#define LD_CLLCOUNT 0x04 +#define LD_ARGS 0x08 +#define LD_STRINGARGS 0x10 +#define LD_EXECUTORDELAY 0x20 +#define LD_SIDE1 0x40 +#define LD_SIDE2 0x80 -// diff2 flags -#define LD_S2TEXOFF 0x01 -#define LD_S2TOPTEX 0x02 -#define LD_S2BOTTEX 0x04 -#define LD_S2MIDTEX 0x08 -#define LD_ARGS 0x10 -#define LD_STRINGARGS 0x20 -#define LD_EXECUTORDELAY 0x40 +// sidedef flags +enum +{ + LD_SDTEXOFFX = 1, + LD_SDTEXOFFY = 1<<1, + LD_SDTOPTEX = 1<<2, + LD_SDBOTTEX = 1<<3, + LD_SDMIDTEX = 1<<4, + LD_SDTOPOFFX = 1<<5, + LD_SDTOPOFFY = 1<<6, + LD_SDMIDOFFX = 1<<7, + LD_SDMIDOFFY = 1<<8, + LD_SDBOTOFFX = 1<<9, + LD_SDBOTOFFY = 1<<10, + LD_SDTOPSCALEX = 1<<11, + LD_SDTOPSCALEY = 1<<12, + LD_SDMIDSCALEX = 1<<13, + LD_SDMIDSCALEY = 1<<14, + LD_SDBOTSCALEX = 1<<15, + LD_SDBOTSCALEY = 1<<16, + LD_SDLIGHT = 1<<17, + LD_SDTOPLIGHT = 1<<18, + LD_SDMIDLIGHT = 1<<19, + LD_SDBOTLIGHT = 1<<20, + LD_SDREPEATCNT = 1<<21, + LD_SDFLAGS = 1<<22 +}; static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli) { @@ -1271,18 +1290,103 @@ static void UnArchiveSectors(void) } } +static UINT32 GetSideDiff(const side_t *si, const side_t *spawnsi) +{ + UINT32 diff = 0; + if (si->textureoffset != spawnsi->textureoffset) + diff |= LD_SDTEXOFFX; + if (si->rowoffset != spawnsi->rowoffset) + diff |= LD_SDTEXOFFY; + //SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures. + if (si->toptexture != spawnsi->toptexture) + diff |= LD_SDTOPTEX; + if (si->bottomtexture != spawnsi->bottomtexture) + diff |= LD_SDBOTTEX; + if (si->midtexture != spawnsi->midtexture) + diff |= LD_SDMIDTEX; + if (si->offsetx_top != spawnsi->offsetx_top) + diff |= LD_SDTOPOFFX; + if (si->offsetx_mid != spawnsi->offsetx_mid) + diff |= LD_SDMIDOFFX; + if (si->offsetx_bottom != spawnsi->offsetx_bottom) + diff |= LD_SDBOTOFFX; + if (si->offsety_top != spawnsi->offsety_top) + diff |= LD_SDTOPOFFY; + if (si->offsety_mid != spawnsi->offsety_mid) + diff |= LD_SDMIDOFFY; + if (si->offsety_bottom != spawnsi->offsety_bottom) + diff |= LD_SDBOTOFFY; + if (si->scalex_top != spawnsi->scalex_top) + diff |= LD_SDTOPSCALEX; + if (si->scalex_mid != spawnsi->scalex_mid) + diff |= LD_SDMIDSCALEX; + if (si->scalex_bottom != spawnsi->scalex_bottom) + diff |= LD_SDBOTSCALEX; + if (si->scaley_top != spawnsi->scaley_top) + diff |= LD_SDTOPSCALEY; + if (si->scaley_mid != spawnsi->scaley_mid) + diff |= LD_SDMIDSCALEY; + if (si->scaley_bottom != spawnsi->scaley_bottom) + diff |= LD_SDBOTSCALEY; + if (si->repeatcnt != spawnsi->repeatcnt) + diff |= LD_SDREPEATCNT; + return diff; +} + +static void ArchiveSide(const side_t *si, UINT32 diff) +{ + WRITEUINT32(save_p, diff); + + if (diff & LD_SDTEXOFFX) + WRITEFIXED(save_p, si->textureoffset); + if (diff & LD_SDTEXOFFY) + WRITEFIXED(save_p, si->rowoffset); + if (diff & LD_SDTOPTEX) + WRITEINT32(save_p, si->toptexture); + if (diff & LD_SDBOTTEX) + WRITEINT32(save_p, si->bottomtexture); + if (diff & LD_SDMIDTEX) + WRITEINT32(save_p, si->midtexture); + if (diff & LD_SDTOPOFFX) + WRITEFIXED(save_p, si->offsetx_top); + if (diff & LD_SDMIDOFFX) + WRITEFIXED(save_p, si->offsetx_mid); + if (diff & LD_SDBOTOFFX) + WRITEFIXED(save_p, si->offsetx_bottom); + if (diff & LD_SDTOPOFFY) + WRITEFIXED(save_p, si->offsety_top); + if (diff & LD_SDMIDOFFY) + WRITEFIXED(save_p, si->offsety_mid); + if (diff & LD_SDBOTOFFY) + WRITEFIXED(save_p, si->offsety_bottom); + if (diff & LD_SDTOPSCALEX) + WRITEFIXED(save_p, si->scalex_top); + if (diff & LD_SDMIDSCALEX) + WRITEFIXED(save_p, si->scalex_mid); + if (diff & LD_SDBOTSCALEX) + WRITEFIXED(save_p, si->scalex_bottom); + if (diff & LD_SDTOPSCALEY) + WRITEFIXED(save_p, si->scaley_top); + if (diff & LD_SDMIDSCALEY) + WRITEFIXED(save_p, si->scaley_mid); + if (diff & LD_SDBOTSCALEY) + WRITEFIXED(save_p, si->scaley_bottom); + if (diff & LD_SDREPEATCNT) + WRITEINT16(save_p, si->repeatcnt); +} + static void ArchiveLines(void) { size_t i; const line_t *li = lines; const line_t *spawnli = spawnlines; - const side_t *si; - const side_t *spawnsi; - UINT8 diff, diff2; // no diff3 + UINT8 diff; + UINT32 diff2; + UINT32 diff3; for (i = 0; i < numlines; i++, spawnli++, li++) { - diff = diff2 = 0; + diff = diff2 = diff3 = 0; if (li->special != spawnli->special) diff |= LD_SPECIAL; @@ -1291,84 +1395,44 @@ static void ArchiveLines(void) diff |= LD_CLLCOUNT; if (!P_AreArgsEqual(li, spawnli)) - diff2 |= LD_ARGS; + diff |= LD_ARGS; if (!P_AreStringArgsEqual(li, spawnli)) - diff2 |= LD_STRINGARGS; + diff |= LD_STRINGARGS; if (li->executordelay != spawnli->executordelay) - diff2 |= LD_EXECUTORDELAY; + diff |= LD_EXECUTORDELAY; if (li->sidenum[0] != 0xffff) { - si = &sides[li->sidenum[0]]; - spawnsi = &spawnsides[li->sidenum[0]]; - if (si->textureoffset != spawnsi->textureoffset) - diff |= LD_S1TEXOFF; - //SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures. - if (si->toptexture != spawnsi->toptexture) - diff |= LD_S1TOPTEX; - if (si->bottomtexture != spawnsi->bottomtexture) - diff |= LD_S1BOTTEX; - if (si->midtexture != spawnsi->midtexture) - diff |= LD_S1MIDTEX; + diff2 = GetSideDiff(&sides[li->sidenum[0]], &spawnsides[li->sidenum[0]]); + if (diff2) + diff |= LD_SIDE1; } if (li->sidenum[1] != 0xffff) { - si = &sides[li->sidenum[1]]; - spawnsi = &spawnsides[li->sidenum[1]]; - if (si->textureoffset != spawnsi->textureoffset) - diff2 |= LD_S2TEXOFF; - if (si->toptexture != spawnsi->toptexture) - diff2 |= LD_S2TOPTEX; - if (si->bottomtexture != spawnsi->bottomtexture) - diff2 |= LD_S2BOTTEX; - if (si->midtexture != spawnsi->midtexture) - diff2 |= LD_S2MIDTEX; + diff3 = GetSideDiff(&sides[li->sidenum[1]], &spawnsides[li->sidenum[1]]); + if (diff3) + diff |= LD_SIDE2; } - if (diff2) - diff |= LD_DIFF2; - if (diff) { WRITEINT16(save_p, i); WRITEUINT8(save_p, diff); - if (diff & LD_DIFF2) - WRITEUINT8(save_p, diff2); if (diff & LD_FLAG) WRITEINT16(save_p, li->flags); if (diff & LD_SPECIAL) WRITEINT16(save_p, li->special); if (diff & LD_CLLCOUNT) WRITEINT16(save_p, li->callcount); - - si = &sides[li->sidenum[0]]; - if (diff & LD_S1TEXOFF) - WRITEFIXED(save_p, si->textureoffset); - if (diff & LD_S1TOPTEX) - WRITEINT32(save_p, si->toptexture); - if (diff & LD_S1BOTTEX) - WRITEINT32(save_p, si->bottomtexture); - if (diff & LD_S1MIDTEX) - WRITEINT32(save_p, si->midtexture); - - si = &sides[li->sidenum[1]]; - if (diff2 & LD_S2TEXOFF) - WRITEFIXED(save_p, si->textureoffset); - if (diff2 & LD_S2TOPTEX) - WRITEINT32(save_p, si->toptexture); - if (diff2 & LD_S2BOTTEX) - WRITEINT32(save_p, si->bottomtexture); - if (diff2 & LD_S2MIDTEX) - WRITEINT32(save_p, si->midtexture); - if (diff2 & LD_ARGS) + if (diff & LD_ARGS) { UINT8 j; for (j = 0; j < NUMLINEARGS; j++) WRITEINT32(save_p, li->args[j]); } - if (diff2 & LD_STRINGARGS) + if (diff & LD_STRINGARGS) { UINT8 j; for (j = 0; j < NUMLINESTRINGARGS; j++) @@ -1387,19 +1451,64 @@ static void ArchiveLines(void) WRITECHAR(save_p, li->stringargs[j][k]); } } - if (diff2 & LD_EXECUTORDELAY) + if (diff & LD_EXECUTORDELAY) WRITEINT32(save_p, li->executordelay); + if (diff & LD_SIDE1) + ArchiveSide(&sides[li->sidenum[0]], diff2); + if (diff & LD_SIDE2) + ArchiveSide(&sides[li->sidenum[1]], diff3); } } WRITEUINT16(save_p, 0xffff); } +static void UnArchiveSide(side_t *si) +{ + UINT32 diff = READUINT32(save_p); + + if (diff & LD_SDTEXOFFX) + si->textureoffset = READFIXED(save_p); + if (diff & LD_SDTEXOFFY) + si->rowoffset = READFIXED(save_p); + if (diff & LD_SDTOPTEX) + si->toptexture = READINT32(save_p); + if (diff & LD_SDBOTTEX) + si->bottomtexture = READINT32(save_p); + if (diff & LD_SDMIDTEX) + si->midtexture = READINT32(save_p); + if (diff & LD_SDTOPOFFX) + si->offsetx_top = READFIXED(save_p); + if (diff & LD_SDMIDOFFX) + si->offsetx_mid = READFIXED(save_p); + if (diff & LD_SDBOTOFFX) + si->offsetx_bottom = READFIXED(save_p); + if (diff & LD_SDTOPOFFY) + si->offsety_top = READFIXED(save_p); + if (diff & LD_SDMIDOFFY) + si->offsety_mid = READFIXED(save_p); + if (diff & LD_SDBOTOFFY) + si->offsety_bottom = READFIXED(save_p); + if (diff & LD_SDTOPSCALEX) + si->scalex_top = READFIXED(save_p); + if (diff & LD_SDMIDSCALEX) + si->scalex_mid = READFIXED(save_p); + if (diff & LD_SDBOTSCALEX) + si->scalex_bottom = READFIXED(save_p); + if (diff & LD_SDTOPSCALEY) + si->scaley_top = READFIXED(save_p); + if (diff & LD_SDMIDSCALEY) + si->scaley_mid = READFIXED(save_p); + if (diff & LD_SDBOTSCALEY) + si->scaley_bottom = READFIXED(save_p); + if (diff & LD_SDREPEATCNT) + si->repeatcnt = READINT16(save_p); +} + static void UnArchiveLines(void) { UINT16 i; line_t *li; - side_t *si; - UINT8 diff, diff2; // no diff3 + UINT8 diff; for (;;) { @@ -1413,44 +1522,19 @@ static void UnArchiveLines(void) diff = READUINT8(save_p); li = &lines[i]; - if (diff & LD_DIFF2) - diff2 = READUINT8(save_p); - else - diff2 = 0; - if (diff & LD_FLAG) li->flags = READINT16(save_p); if (diff & LD_SPECIAL) li->special = READINT16(save_p); if (diff & LD_CLLCOUNT) li->callcount = READINT16(save_p); - - si = &sides[li->sidenum[0]]; - if (diff & LD_S1TEXOFF) - si->textureoffset = READFIXED(save_p); - if (diff & LD_S1TOPTEX) - si->toptexture = READINT32(save_p); - if (diff & LD_S1BOTTEX) - si->bottomtexture = READINT32(save_p); - if (diff & LD_S1MIDTEX) - si->midtexture = READINT32(save_p); - - si = &sides[li->sidenum[1]]; - if (diff2 & LD_S2TEXOFF) - si->textureoffset = READFIXED(save_p); - if (diff2 & LD_S2TOPTEX) - si->toptexture = READINT32(save_p); - if (diff2 & LD_S2BOTTEX) - si->bottomtexture = READINT32(save_p); - if (diff2 & LD_S2MIDTEX) - si->midtexture = READINT32(save_p); - if (diff2 & LD_ARGS) + if (diff & LD_ARGS) { UINT8 j; for (j = 0; j < NUMLINEARGS; j++) li->args[j] = READINT32(save_p); } - if (diff2 & LD_STRINGARGS) + if (diff & LD_STRINGARGS) { UINT8 j; for (j = 0; j < NUMLINESTRINGARGS; j++) @@ -1471,9 +1555,12 @@ static void UnArchiveLines(void) li->stringargs[j][len] = '\0'; } } - if (diff2 & LD_EXECUTORDELAY) + if (diff & LD_EXECUTORDELAY) li->executordelay = READINT32(save_p); - + if (diff & LD_SIDE1) + UnArchiveSide(&sides[li->sidenum[0]]); + if (diff & LD_SIDE2) + UnArchiveSide(&sides[li->sidenum[1]]); } } diff --git a/src/p_setup.c b/src/p_setup.c index 94dfb75ee..79607aea4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1347,11 +1347,11 @@ static void P_LoadSidedefs(UINT8 *data) } sd->rowoffset = SHORT(msd->rowoffset)<offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; - sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; + sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bottom = 0; + sd->offsety_top = sd->offsety_mid = sd->offsety_bottom = 0; - sd->scalex_top = sd->scalex_mid = sd->scalex_bot = FRACUNIT; - sd->scaley_top = sd->scaley_mid = sd->scaley_bot = FRACUNIT; + sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT; + sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT; P_SetSidedefSector(i, SHORT(msd->sector)); @@ -1886,25 +1886,25 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char else if (fastcmp(param, "offsetx_mid")) sides[i].offsetx_mid = atol(val) << FRACBITS; else if (fastcmp(param, "offsetx_bottom")) - sides[i].offsetx_bot = atol(val) << FRACBITS; + sides[i].offsetx_bottom = atol(val) << FRACBITS; else if (fastcmp(param, "offsety_top")) sides[i].offsety_top = atol(val) << FRACBITS; else if (fastcmp(param, "offsety_mid")) sides[i].offsety_mid = atol(val) << FRACBITS; else if (fastcmp(param, "offsety_bottom")) - sides[i].offsety_bot = atol(val) << FRACBITS; + sides[i].offsety_bottom = atol(val) << FRACBITS; else if (fastcmp(param, "scalex_top")) sides[i].scalex_top = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "scalex_mid")) sides[i].scalex_mid = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "scalex_bottom")) - sides[i].scalex_bot = FLOAT_TO_FIXED(atof(val)); + sides[i].scalex_bottom = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "scaley_top")) sides[i].scaley_top = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "scaley_mid")) sides[i].scaley_mid = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "scaley_bottom")) - sides[i].scaley_bot = FLOAT_TO_FIXED(atof(val)); + sides[i].scaley_bottom = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "texturetop")) sides[i].toptexture = R_TextureNumForName(val); else if (fastcmp(param, "texturebottom")) @@ -2609,10 +2609,10 @@ static void P_WriteTextmap(void) fprintf(f, "offsetx_mid = %d;\n", wsides[i].offsetx_mid >> FRACBITS); if (wsides[i].offsety_mid != 0) fprintf(f, "offsety_mid = %d;\n", wsides[i].offsety_mid >> FRACBITS); - if (wsides[i].offsetx_bot != 0) - fprintf(f, "offsetx_bottom = %d;\n", wsides[i].offsetx_bot >> FRACBITS); - if (wsides[i].offsety_bot != 0) - fprintf(f, "offsety_bottom = %d;\n", wsides[i].offsety_bot >> FRACBITS); + if (wsides[i].offsetx_bottom != 0) + fprintf(f, "offsetx_bottom = %d;\n", wsides[i].offsetx_bottom >> FRACBITS); + if (wsides[i].offsety_bottom != 0) + fprintf(f, "offsety_bottom = %d;\n", wsides[i].offsety_bottom >> FRACBITS); if (wsides[i].scalex_top != FRACUNIT) fprintf(f, "scalex_top = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_top)); if (wsides[i].scaley_top != FRACUNIT) @@ -2621,10 +2621,10 @@ static void P_WriteTextmap(void) fprintf(f, "scalex_mid = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_mid)); if (wsides[i].scaley_mid != FRACUNIT) fprintf(f, "scaley_mid = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_mid)); - if (wsides[i].scalex_bot != FRACUNIT) - fprintf(f, "scalex_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_bot)); - if (wsides[i].scaley_bot != FRACUNIT) - fprintf(f, "scaley_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_bot)); + if (wsides[i].scalex_bottom != FRACUNIT) + fprintf(f, "scalex_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_bottom)); + if (wsides[i].scaley_bottom != FRACUNIT) + fprintf(f, "scaley_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_bottom)); if (wsides[i].toptexture > 0 && wsides[i].toptexture < numtextures) fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name); if (wsides[i].bottomtexture > 0 && wsides[i].bottomtexture < numtextures) @@ -3001,10 +3001,10 @@ static void P_LoadTextmap(void) // Defaults. sd->textureoffset = 0; sd->rowoffset = 0; - sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; - sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; - sd->scalex_top = sd->scalex_mid = sd->scalex_bot = FRACUNIT; - sd->scaley_top = sd->scaley_mid = sd->scaley_bot = FRACUNIT; + sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bottom = 0; + sd->offsety_top = sd->offsety_mid = sd->offsety_bottom = 0; + sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT; + sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT; sd->toptexture = R_TextureNumForName("-"); sd->midtexture = R_TextureNumForName("-"); sd->bottomtexture = R_TextureNumForName("-"); diff --git a/src/r_defs.h b/src/r_defs.h index 82d752260..c9ac42c71 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -559,11 +559,11 @@ typedef struct fixed_t rowoffset; // per-texture offsets for UDMF - fixed_t offsetx_top, offsetx_mid, offsetx_bot; - fixed_t offsety_top, offsety_mid, offsety_bot; + fixed_t offsetx_top, offsetx_mid, offsetx_bottom; + fixed_t offsety_top, offsety_mid, offsety_bottom; - fixed_t scalex_top, scalex_mid, scalex_bot; - fixed_t scaley_top, scaley_mid, scaley_bot; + fixed_t scalex_top, scalex_mid, scalex_bottom; + fixed_t scaley_top, scaley_mid, scaley_bottom; // Texture indices. // We do not maintain names here. diff --git a/src/r_segs.c b/src/r_segs.c index c7d77fa33..8a8827c10 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2043,7 +2043,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) } fixed_t toprowoffset = sidedef->rowoffset + sidedef->offsety_top; - fixed_t botrowoffset = sidedef->rowoffset + sidedef->offsety_bot; + fixed_t botrowoffset = sidedef->rowoffset + sidedef->offsety_bottom; // check TOP TEXTURE if (!bothceilingssky // never draw the top texture if on @@ -2092,8 +2092,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // bottom texture bottomtexture = R_GetTextureNum(sidedef->bottomtexture); - rw_bottomtexturescalex = sidedef->scalex_bot; - rw_bottomtexturescaley = sidedef->scaley_bot; + rw_bottomtexturescalex = sidedef->scalex_bottom; + rw_bottomtexturescaley = sidedef->scaley_bottom; rw_invbottomtexturescalex = FixedDiv(FRACUNIT, rw_bottomtexturescalex); @@ -2418,7 +2418,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_offset_top = sideoffset + sidedef->offsetx_top; rw_offset_mid = sideoffset + sidedef->offsetx_mid; - rw_offset_bottom = sideoffset + sidedef->offsetx_bot; + rw_offset_bottom = sideoffset + sidedef->offsetx_bottom; rw_offsetx = rw_offset_mid; if (rw_midtexturescalex < 0) From c53fd6de1660e8255318a0fd8caacaf1439755bf Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 01:27:02 -0300 Subject: [PATCH 38/85] Fix minor issues with 3D floor sides in OpenGL --- src/hardware/hw_main.c | 69 +++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 8686a59e8..8e5421040 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1607,15 +1607,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; - texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); + side_t *side = &sides[rover->master->sidenum[0]]; if (rover->master->flags & ML_TFERLINE) { size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; newline = rover->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + side = &sides[newline->sidenum[0]]; } + texnum = R_GetTextureNum(side->midtexture); + h = P_GetFFloorTopZAt (rover, v1x, v1y); hS = P_GetFFloorTopZAt (rover, v2x, v2y); l = P_GetFFloorBottomZAt(rover, v1x, v1y); @@ -1631,14 +1633,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom l = lowcut; lS = lowcutslope; } - //Hurdler: HW code starts here - //FIXME: check if peging is correct - // set top/bottom coords + // set top/bottom coords wallVerts[3].y = FIXED_TO_FLOAT(h); wallVerts[2].y = FIXED_TO_FLOAT(hS); wallVerts[0].y = FIXED_TO_FLOAT(l); wallVerts[1].y = FIXED_TO_FLOAT(lS); + if (rover->fofflags & FOF_FOG) { wallVerts[3].t = wallVerts[2].t = 0; @@ -1648,31 +1649,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } else { - fixed_t texturevpeg; - boolean attachtobottom = false; - boolean slopeskew = false; // skew FOF walls with slopes? - // Wow, how was this missing from OpenGL for so long? // ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software // -- Monster Iestyn 26/06/18 - if (newline) - { - texturevpeg = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid; - attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM); - slopeskew = !!(newline->flags & ML_SKEWTD); - } - else - { - texturevpeg = sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid; - attachtobottom = !!(gl_linedef->flags & ML_DONTPEGBOTTOM); - slopeskew = !!(rover->master->flags & ML_SKEWTD); - } + fixed_t texturevpeg = side->rowoffset + side->offsety_mid; + boolean attachtobottom = !!(rover->master->flags & ML_DONTPEGBOTTOM); grTex = HWR_GetTexture(texnum); - xscale = FixedToFloat(sides[rover->master->sidenum[0]].scalex_mid); - yscale = FixedToFloat(sides[rover->master->sidenum[0]].scaley_mid); + xscale = FixedToFloat(side->scalex_mid); + yscale = FixedToFloat(side->scaley_mid); - if (!slopeskew) // no skewing + if (!(rover->master->flags & ML_SKEWTD)) // no skewing { if (attachtobottom) texturevpeg -= (*rover->topheight - *rover->bottomheight) * yscale; @@ -1698,9 +1685,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } } - wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX; } + if (rover->fofflags & FOF_FOG) { FBITFIELD blendmode; @@ -1767,14 +1755,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; - texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); + side_t *side = &sides[rover->master->sidenum[0]]; if (rover->master->flags & ML_TFERLINE) { size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; newline = rover->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + side = &sides[newline->sidenum[0]]; } + + texnum = R_GetTextureNum(side->midtexture); + h = P_GetFFloorTopZAt (rover, v1x, v1y); hS = P_GetFFloorTopZAt (rover, v2x, v2y); l = P_GetFFloorBottomZAt(rover, v1x, v1y); @@ -1808,22 +1799,16 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else { grTex = HWR_GetTexture(texnum); - xscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scalex_mid) * grTex->scaleX; - yscale = FIXED_TO_FLOAT(sides[rover->master->sidenum[0]].scaley_mid) * grTex->scaleY; + xscale = FixedToFloat(side->scalex_mid); + yscale = FixedToFloat(side->scaley_mid); - if (newline) - { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid) * yscale; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) + sides[newline->sidenum[0]].offsety_mid) * yscale; - } - else - { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid) * yscale; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid)) * yscale; - } + fixed_t diff = (*rover->topheight - h) * yscale; - wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * xscale; - wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * xscale; + wallVerts[3].t = wallVerts[2].t = (diff + side->rowoffset + side->offsety_mid) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (((h - l) * yscale) + (diff + side->rowoffset + side->offsety_mid)) * grTex->scaleY; + + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX; } if (rover->fofflags & FOF_FOG) From 2e4fab3f1a268fb05b1519ff9ee0ff58c8e1e15e Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 01:29:43 -0300 Subject: [PATCH 39/85] Remove unneeded code from HWR_RenderPlane and HWR_RenderPolyObjectPlane --- src/hardware/hw_main.c | 72 ++++++++---------------------------------- 1 file changed, 14 insertions(+), 58 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 8e5421040..3a347196d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -375,9 +375,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool float height; // constant y for all points on the convex flat polygon float flatxref, flatyref, anglef = 0.0f; float fflatwidth = 64.0f, fflatheight = 64.0f; - UINT16 flatflag = 63; - - boolean texflat = false; float tempxsow, tempytow; float scrollx = 0.0f, scrolly = 0.0f; @@ -432,8 +429,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool if (levelflat->type == LEVELFLAT_FLAT) { size_t len = W_LumpLength(levelflat->u.flat.lumpnum); - flatflag = R_GetFlatSize(len) - 1; - fflatwidth = fflatheight = (float)(flatflag + 1); + unsigned flatflag = R_GetFlatSize(len); + fflatwidth = fflatheight = (float)flatflag; } else { @@ -447,15 +444,14 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool fflatwidth = levelflat->width; fflatheight = levelflat->height; } - texflat = true; } } else // set no texture HWR_SetCurrentTexture(NULL); // reference point for flat texture coord for each vertex around the polygon - flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth); - flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight); + flatxref = 0.0; + flatyref = 0.0; // transform if (FOFsector != NULL) @@ -489,29 +485,12 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool } } - if (angle) // Only needs to be done if there's an altered angle - { - tempxsow = flatxref; - tempytow = flatyref; - - anglef = ANG2RAD(InvAngle(angle)); - - flatxref = (tempxsow * cos(anglef)) - (tempytow * sin(anglef)); - flatyref = (tempxsow * sin(anglef)) + (tempytow * cos(anglef)); - } + anglef = ANG2RAD(InvAngle(angle)); #define SETUP3DVERT(vert, vx, vy) {\ /* Hurdler: add scrolling texture on floor/ceiling */\ - if (texflat)\ - {\ - vert->s = (float)((vx) / fflatwidth) + scrollx;\ - vert->t = -(float)((vy) / fflatheight) + scrolly;\ - }\ - else\ - {\ - vert->s = (float)(((vx) / fflatwidth) - flatxref + scrollx);\ - vert->t = (float)(flatyref - ((vy) / fflatheight) + scrolly);\ - }\ + vert->s = (float)(((vx) / fflatwidth) - flatxref + scrollx);\ + vert->t = (float)(flatyref - ((vy) / fflatheight) + scrolly);\ \ /* Need to rotate before translate */\ if (angle) /* Only needs to be done if there's an altered angle */\ @@ -2664,9 +2643,6 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon float flatxref, flatyref; float fflatwidth = 64.0f, fflatheight = 64.0f; - UINT16 flatflag = 63; - - boolean texflat = false; float scrollx = 0.0f, scrolly = 0.0f; float tempxsow, tempytow, anglef = 0.0f; @@ -2697,8 +2673,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, if (levelflat->type == LEVELFLAT_FLAT) { size_t len = W_LumpLength(levelflat->u.flat.lumpnum); - flatflag = R_GetFlatSize(len) - 1; - fflatwidth = fflatheight = (float)(flatflag + 1); + unsigned flatflag = R_GetFlatSize(len); + fflatwidth = fflatheight = (float)flatflag; } else { @@ -2712,18 +2688,15 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fflatwidth = levelflat->width; fflatheight = levelflat->height; } - texflat = true; } } else // set no texture HWR_SetCurrentTexture(NULL); // reference point for flat texture coord for each vertex around the polygon - flatxref = FIXED_TO_FLOAT(polysector->origVerts[0].x); - flatyref = FIXED_TO_FLOAT(polysector->origVerts[0].y); + flatxref = 0.0; + flatyref = 0.0; - flatxref = (float)(((fixed_t)flatxref & (~flatflag)) / fflatwidth); - flatyref = (float)(((fixed_t)flatyref & (~flatflag)) / fflatheight); // transform v3d = planeVerts; @@ -2759,31 +2732,14 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, } } - if (angle) // Only needs to be done if there's an altered angle - { - tempxsow = flatxref; - tempytow = flatyref; - - anglef = ANG2RAD(InvAngle(angle)); - - flatxref = (tempxsow * cos(anglef)) - (tempytow * sin(anglef)); - flatyref = (tempxsow * sin(anglef)) + (tempytow * cos(anglef)); - } + anglef = ANG2RAD(InvAngle(angle)); for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++) { // Go from the polysector's original vertex locations // Means the flat is offset based on the original vertex locations - if (texflat) - { - v3d->s = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx; - v3d->t = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly; - } - else - { - v3d->s = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); - v3d->t = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); - } + v3d->s = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); + v3d->t = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle From 468b44831661acfe4d10c1a657391fe2e86e7465 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 01:52:57 -0300 Subject: [PATCH 40/85] Add sector texture scale fields --- src/lua_maplib.c | 44 ++++++++++++++++++++++++++++++++------------ src/p_saveg.c | 28 ++++++++++++++++++++++++++++ src/p_setup.c | 22 ++++++++++++++++++++++ src/p_spec.c | 4 ++++ src/r_bsp.c | 44 +++++++++++++++++++++++++++++++++++--------- src/r_defs.h | 8 ++++++++ src/r_plane.c | 12 ++++++++---- src/r_plane.h | 4 ++-- src/r_segs.c | 4 ++++ 9 files changed, 143 insertions(+), 27 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index d81d28ba1..aca07b1c3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -35,10 +35,14 @@ enum sector_e { sector_floorpic, sector_floorxoffset, sector_flooryoffset, + sector_floorxscale, + sector_flooryscale, sector_floorangle, sector_ceilingpic, sector_ceilingxoffset, sector_ceilingyoffset, + sector_ceilingxscale, + sector_ceilingyscale, sector_ceilingangle, sector_lightlevel, sector_floorlightlevel, @@ -73,10 +77,14 @@ static const char *const sector_opt[] = { "floorpic", "floorxoffset", "flooryoffset", + "floorxscale", + "flooryscale", "floorangle", "ceilingpic", "ceilingxoffset", "ceilingyoffset", + "ceilingxscale", + "ceilingyscale", "ceilingangle", "lightlevel", "floorlightlevel", @@ -666,20 +674,20 @@ static int sector_get(lua_State *L) return 1; } case sector_floorxoffset: - { lua_pushfixed(L, sector->floorxoffset); return 1; - } case sector_flooryoffset: - { lua_pushfixed(L, sector->flooryoffset); return 1; - } + case sector_floorxscale: + lua_pushfixed(L, sector->floorxscale); + return 1; + case sector_flooryscale: + lua_pushfixed(L, sector->flooryscale); + return 1; case sector_floorangle: - { lua_pushangle(L, sector->floorangle); return 1; - } case sector_ceilingpic: // ceilingpic { levelflat_t *levelflat = &levelflats[sector->ceilingpic]; @@ -690,20 +698,20 @@ static int sector_get(lua_State *L) return 1; } case sector_ceilingxoffset: - { lua_pushfixed(L, sector->ceilingxoffset); return 1; - } case sector_ceilingyoffset: - { lua_pushfixed(L, sector->ceilingyoffset); return 1; - } + case sector_ceilingxscale: + lua_pushfixed(L, sector->ceilingxscale); + return 1; + case sector_ceilingyscale: + lua_pushfixed(L, sector->ceilingyscale); + return 1; case sector_ceilingangle: - { lua_pushangle(L, sector->ceilingangle); return 1; - } case sector_lightlevel: lua_pushinteger(L, sector->lightlevel); return 1; @@ -852,6 +860,12 @@ static int sector_set(lua_State *L) case sector_flooryoffset: sector->flooryoffset = luaL_checkfixed(L, 3); break; + case sector_floorxscale: + sector->floorxscale = luaL_checkfixed(L, 3); + break; + case sector_flooryscale: + sector->flooryscale = luaL_checkfixed(L, 3); + break; case sector_floorangle: sector->floorangle = luaL_checkangle(L, 3); break; @@ -864,6 +878,12 @@ static int sector_set(lua_State *L) case sector_ceilingyoffset: sector->ceilingyoffset = luaL_checkfixed(L, 3); break; + case sector_ceilingxscale: + sector->ceilingxscale = luaL_checkfixed(L, 3); + break; + case sector_ceilingyscale: + sector->ceilingyscale = luaL_checkfixed(L, 3); + break; case sector_ceilingangle: sector->ceilingangle = luaL_checkangle(L, 3); break; diff --git a/src/p_saveg.c b/src/p_saveg.c index 4ab7aeccc..eaaf10b86 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -867,6 +867,10 @@ static void P_NetUnArchiveWaypoints(void) #define SD_TRIGGERTAG 0x02 #define SD_TRIGGERER 0x04 #define SD_GRAVITY 0x08 +#define SD_FXSCALE 0x10 +#define SD_FYSCALE 0x20 +#define SD_CXSCALE 0x40 +#define SD_CYSCALE 0x80 #define LD_FLAG 0x01 #define LD_SPECIAL 0x02 @@ -1054,6 +1058,14 @@ static void ArchiveSectors(void) diff2 |= SD_CXOFFS; if (ss->ceilingyoffset != spawnss->ceilingyoffset) diff2 |= SD_CYOFFS; + if (ss->floorxscale != spawnss->floorxscale) + diff2 |= SD_FXSCALE; + if (ss->flooryscale != spawnss->flooryscale) + diff2 |= SD_FYSCALE; + if (ss->ceilingxscale != spawnss->ceilingxscale) + diff2 |= SD_CXSCALE; + if (ss->ceilingyscale != spawnss->ceilingyscale) + diff2 |= SD_CYSCALE; if (ss->floorangle != spawnss->floorangle) diff2 |= SD_FLOORANG; if (ss->ceilingangle != spawnss->ceilingangle) @@ -1164,6 +1176,14 @@ static void ArchiveSectors(void) WRITEUINT8(save_p, ss->triggerer); if (diff4 & SD_GRAVITY) WRITEFIXED(save_p, ss->gravity); + if (diff4 & SD_FXSCALE) + WRITEFIXED(save_p, ss->floorxscale); + if (diff4 & SD_FYSCALE) + WRITEFIXED(save_p, ss->flooryscale); + if (diff4 & SD_CXSCALE) + WRITEFIXED(save_p, ss->ceilingxscale); + if (diff4 & SD_CYSCALE) + WRITEFIXED(save_p, ss->ceilingyscale); if (diff & SD_FFLOORS) ArchiveFFloors(ss); } @@ -1284,6 +1304,14 @@ static void UnArchiveSectors(void) sectors[i].triggerer = READUINT8(save_p); if (diff4 & SD_GRAVITY) sectors[i].gravity = READFIXED(save_p); + if (diff4 & SD_FXSCALE) + sectors[i].floorxscale = READFIXED(save_p); + if (diff4 & SD_FYSCALE) + sectors[i].flooryscale = READFIXED(save_p); + if (diff4 & SD_CXSCALE) + sectors[i].ceilingxscale = READFIXED(save_p); + if (diff4 & SD_CYSCALE) + sectors[i].ceilingyscale = READFIXED(save_p); if (diff & SD_FFLOORS) UnArchiveFFloors(§ors[i]); diff --git a/src/p_setup.c b/src/p_setup.c index 79607aea4..cc80973d9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1055,6 +1055,9 @@ static void P_LoadSectors(UINT8 *data) ss->floorxoffset = ss->flooryoffset = 0; ss->ceilingxoffset = ss->ceilingyoffset = 0; + ss->floorxscale = ss->flooryscale = FRACUNIT; + ss->ceilingxscale = ss->ceilingyscale = FRACUNIT; + ss->floorangle = ss->ceilingangle = 0; ss->floorlightlevel = ss->ceilinglightlevel = 0; @@ -1691,6 +1694,14 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char sectors[i].ceilingxoffset = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "ypanningceiling")) sectors[i].ceilingyoffset = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "xscalefloor")) + sectors[i].floorxscale = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "yscalefloor")) + sectors[i].flooryscale = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "xscaleceiling")) + sectors[i].ceilingxscale = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "yscaleceiling")) + sectors[i].ceilingyscale = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "rotationfloor")) sectors[i].floorangle = FixedAngle(FLOAT_TO_FIXED(atof(val))); else if (fastcmp(param, "rotationceiling")) @@ -2680,6 +2691,14 @@ static void P_WriteTextmap(void) fprintf(f, "xpanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingxoffset)); if (tempsec.ceilingyoffset != 0) fprintf(f, "ypanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingyoffset)); + if (tempsec.floorxscale != 0) + fprintf(f, "xscalefloor = %f;\n", FIXED_TO_FLOAT(tempsec.floorxscale)); + if (tempsec.flooryscale != 0) + fprintf(f, "yscalefloor = %f;\n", FIXED_TO_FLOAT(tempsec.flooryscale)); + if (tempsec.ceilingxscale != 0) + fprintf(f, "xscaleceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingxscale)); + if (tempsec.ceilingyscale != 0) + fprintf(f, "yscaleceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingyscale)); if (wsectors[i].floorangle != 0) fprintf(f, "rotationfloor = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].floorangle))); if (wsectors[i].ceilingangle != 0) @@ -2915,6 +2934,9 @@ static void P_LoadTextmap(void) sc->floorxoffset = sc->flooryoffset = 0; sc->ceilingxoffset = sc->ceilingyoffset = 0; + sc->floorxscale = sc->flooryscale = FRACUNIT; + sc->ceilingxscale = sc->ceilingyscale = FRACUNIT; + sc->floorangle = sc->ceilingangle = 0; sc->floorlightlevel = sc->ceilinglightlevel = 0; diff --git a/src/p_spec.c b/src/p_spec.c index aa4ee37cf..8c09ad71d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5597,6 +5597,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I fflr->bottompic = &sec2->floorpic; fflr->bottomxoffs = &sec2->floorxoffset; fflr->bottomyoffs = &sec2->flooryoffset; + fflr->bottomxscale = &sec2->floorxscale; + fflr->bottomyscale = &sec2->flooryscale; fflr->bottomangle = &sec2->floorangle; // Add the ceiling @@ -5605,6 +5607,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I fflr->toplightlevel = &sec2->lightlevel; fflr->topxoffs = &sec2->ceilingxoffset; fflr->topyoffs = &sec2->ceilingyoffset; + fflr->topxscale = &sec2->ceilingxscale; + fflr->topyscale = &sec2->ceilingyscale; fflr->topangle = &sec2->ceilingangle; // Add slopes diff --git a/src/r_bsp.c b/src/r_bsp.c index 42e050adf..d99de5981 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -277,6 +277,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->floorpic = s->floorpic; tempsec->floorxoffset = s->floorxoffset; tempsec->flooryoffset = s->flooryoffset; + tempsec->floorxscale = s->floorxscale; + tempsec->flooryscale = s->flooryscale; tempsec->floorangle = s->floorangle; if (underwater) @@ -287,6 +289,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->ceilingpic = tempsec->floorpic; tempsec->ceilingxoffset = tempsec->floorxoffset; tempsec->ceilingyoffset = tempsec->flooryoffset; + tempsec->ceilingxscale = tempsec->floorxscale; + tempsec->ceilingyscale = tempsec->flooryscale; tempsec->ceilingangle = tempsec->floorangle; } else @@ -294,6 +298,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->ceilingpic = s->ceilingpic; tempsec->ceilingxoffset = s->ceilingxoffset; tempsec->ceilingyoffset = s->ceilingyoffset; + tempsec->ceilingxscale = s->ceilingxscale; + tempsec->ceilingyscale = s->ceilingyscale; tempsec->ceilingangle = s->ceilingangle; } } @@ -317,6 +323,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->floorpic = tempsec->ceilingpic = s->ceilingpic; tempsec->floorxoffset = tempsec->ceilingxoffset = s->ceilingxoffset; tempsec->flooryoffset = tempsec->ceilingyoffset = s->ceilingyoffset; + tempsec->floorxscale = tempsec->ceilingxscale = s->ceilingxscale; + tempsec->flooryscale = tempsec->ceilingyscale = s->ceilingyscale; tempsec->floorangle = tempsec->ceilingangle = s->ceilingangle; if (s->floorpic == skyflatnum) // SKYFIX? @@ -325,6 +333,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->floorpic = tempsec->ceilingpic; tempsec->floorxoffset = tempsec->ceilingxoffset; tempsec->flooryoffset = tempsec->ceilingyoffset; + tempsec->floorxscale = tempsec->ceilingxscale; + tempsec->flooryscale = tempsec->ceilingyscale; tempsec->floorangle = tempsec->ceilingangle; } else @@ -333,6 +343,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->floorpic = s->floorpic; tempsec->floorxoffset = s->floorxoffset; tempsec->flooryoffset = s->flooryoffset; + tempsec->floorxscale = s->floorxscale; + tempsec->flooryscale = s->flooryscale; tempsec->floorangle = s->floorangle; } @@ -362,12 +374,16 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) && back->c_slope == front->c_slope && back->lightlevel == front->lightlevel && !line->sidedef->midtexture - // Check offsets too! + // Check offsets and scale too! && back->floorxoffset == front->floorxoffset && back->flooryoffset == front->flooryoffset + && back->floorxscale == front->floorxscale + && back->flooryscale == front->flooryscale && back->floorangle == front->floorangle && back->ceilingxoffset == front->ceilingxoffset && back->ceilingyoffset == front->ceilingyoffset + && back->ceilingxscale == front->ceilingxscale + && back->ceilingyscale == front->ceilingyscale && back->ceilingangle == front->ceilingangle // Consider altered lighting. && back->floorlightlevel == front->floorlightlevel @@ -909,7 +925,9 @@ static void R_Subsector(size_t num) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope); + frontsector->floorxoffset, frontsector->flooryoffset, + frontsector->floorxscale, frontsector->flooryscale, frontsector->floorangle, + floorcolormap, NULL, NULL, frontsector->f_slope); } else floorplane = NULL; @@ -918,8 +936,9 @@ static void R_Subsector(size_t num) || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) { - ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, - ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle, + ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, + frontsector->ceilingxoffset, frontsector->ceilingyoffset, + frontsector->ceilingxscale, frontsector->ceilingyscale, frontsector->ceilingangle, ceilingcolormap, NULL, NULL, frontsector->c_slope); } else @@ -962,8 +981,9 @@ static void R_Subsector(size_t num) viewz < heightcheck); ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, - *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope); + *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, + *rover->bottomxscale, *rover->bottomyscale, *rover->bottomangle, + *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope); ffloor[numffloors].slope = *rover->b_slope; @@ -991,7 +1011,8 @@ static void R_Subsector(size_t num) 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, + *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, + *rover->topxscale, *rover->topyscale, *rover->topangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope); ffloor[numffloors].slope = *rover->t_slope; @@ -1033,7 +1054,9 @@ static void R_Subsector(size_t num) { light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic, - (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floorxoffset, polysec->flooryoffset, + (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), + polysec->floorxoffset, polysec->flooryoffset, + polysec->floorxscale, polysec->flooryscale, polysec->floorangle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL); // will ffloors be slopable eventually? @@ -1057,7 +1080,10 @@ static void R_Subsector(size_t num) { light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, - (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceilingxoffset, polysec->ceilingyoffset, polysec->ceilingangle-po->angle, + (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), + polysec->ceilingxoffset, polysec->ceilingyoffset, + polysec->ceilingxscale, polysec->ceilingyscale, + polysec->ceilingangle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL); // will ffloors be slopable eventually? diff --git a/src/r_defs.h b/src/r_defs.h index c9ac42c71..3839cb937 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -215,12 +215,16 @@ typedef struct ffloor_s INT16 *toplightlevel; fixed_t *topxoffs; fixed_t *topyoffs; + fixed_t *topxscale; + fixed_t *topyscale; angle_t *topangle; fixed_t *bottomheight; INT32 *bottompic; fixed_t *bottomxoffs; fixed_t *bottomyoffs; + fixed_t *bottomxscale; + fixed_t *bottomyscale; angle_t *bottomangle; // Pointers to pointers. Yup. @@ -426,6 +430,10 @@ typedef struct sector_s fixed_t floorxoffset, flooryoffset; fixed_t ceilingxoffset, ceilingyoffset; + // floor and ceiling texture scale + fixed_t floorxscale, flooryscale; + fixed_t ceilingxscale, ceilingyscale; + // flat angle angle_t floorangle; angle_t ceilingangle; diff --git a/src/r_plane.c b/src/r_plane.c index 29ce26b29..6e186b9bf 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -391,7 +391,8 @@ static visplane_t *new_visplane(unsigned hash) // If not, allocates another of them. // visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, - fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, + fixed_t xoff, fixed_t yoff, fixed_t xscale, fixed_t yscale, + angle_t plangle, extracolormap_t *planecolormap, ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope) { visplane_t *check; @@ -401,6 +402,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, { xoff += viewx; yoff -= viewy; + if (plangle != 0) { // Add the view offset, rotated by the plane angle. @@ -429,6 +431,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } + (void)xscale; + (void)yscale; + // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) { @@ -441,8 +446,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, hash = visplane_hash(picnum, lightlevel, height); for (check = visplanes[hash]; check; check = check->next) { - if (polyobj != check->polyobj) - continue; if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && xoff == check->xoffs && yoff == check->yoffs @@ -450,7 +453,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz && check->viewangle == viewangle && check->plangle == plangle - && check->slope == slope) + && check->slope == slope + && check->polyobj == polyobj) { return check; } diff --git a/src/r_plane.h b/src/r_plane.h index 917e8b041..831d4a6e1 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -75,8 +75,8 @@ void R_ClearPlanes(void); void R_ClearFFloorClips (void); void R_DrawPlanes(void); -visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); +visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, fixed_t xscale, fixed_t yscale, + angle_t plangle, extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_PlaneBounds(visplane_t *plane); diff --git a/src/r_segs.c b/src/r_segs.c index 8a8827c10..987eb014c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1981,6 +1981,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) //SoM: 3/22/2000: Check floor x and y offsets. || backsector->floorxoffset != frontsector->floorxoffset || backsector->flooryoffset != frontsector->flooryoffset + || backsector->floorxscale != frontsector->floorxscale + || backsector->flooryscale != frontsector->flooryscale || backsector->floorangle != frontsector->floorangle //SoM: 3/22/2000: Prevents bleeding. || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum) @@ -2014,6 +2016,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) //SoM: 3/22/2000: Check floor x and y offsets. || backsector->ceilingxoffset != frontsector->ceilingxoffset || backsector->ceilingyoffset != frontsector->ceilingyoffset + || backsector->ceilingxscale != frontsector->ceilingxscale + || backsector->ceilingyscale != frontsector->ceilingyscale || backsector->ceilingangle != frontsector->ceilingangle //SoM: 3/22/2000: Prevents bleeding. || (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum) From da68f4c6693a33f0966c561442cc0046858a256d Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 02:05:08 -0300 Subject: [PATCH 41/85] Sector texture scaling, part 1 --- src/r_plane.c | 29 ++++++++++++++++++++++++----- src/r_plane.h | 1 + 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 6e186b9bf..786ca440c 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -169,6 +169,8 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { ds_xstep = FixedMul(planesin, planeheight) / span; ds_ystep = FixedMul(planecos, planeheight) / span; + ds_xstep = FixedMul(currentplane->xscale, ds_xstep); + ds_ystep = FixedMul(currentplane->yscale, ds_ystep); } else ds_xstep = ds_ystep = FRACUNIT; @@ -188,8 +190,8 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) // to step from those to the proper texture coordinate to start drawing at. // That way, the texture coordinate is always calculated by its position // on the screen and not by its position relative to the edge of the visplane. - ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep; - ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep; + ds_xfrac = xoffs + FixedMul(currentplane->xscale, FixedMul(planecos, distance)) + (x1 - centerx) * ds_xstep; + ds_yfrac = yoffs - FixedMul(currentplane->yscale, FixedMul(planesin, distance)) + (x1 - centerx) * ds_ystep; // Water ripple effect if (planeripple.active) @@ -431,8 +433,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } - (void)xscale; - (void)yscale; + if (!slope) + { + xoff = FixedMul(xoff, xscale); + yoff = FixedMul(yoff, yscale); + } // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) @@ -449,6 +454,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && xoff == check->xoffs && yoff == check->yoffs + && xscale == check->xscale && yscale == check->yscale && planecolormap == check->extra_colormap && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz && check->viewangle == viewangle @@ -474,6 +480,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, check->maxx = -1; check->xoffs = xoff; check->yoffs = yoff; + check->xscale = xscale; + check->yscale = yscale; check->extra_colormap = planecolormap; check->ffloor = pfloor; check->viewx = viewx; @@ -550,6 +558,8 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->lightlevel = pl->lightlevel; new_pl->xoffs = pl->xoffs; new_pl->yoffs = pl->yoffs; + new_pl->xscale = pl->xscale; + new_pl->yscale = pl->yscale; new_pl->extra_colormap = pl->extra_colormap; new_pl->ffloor = pl->ffloor; new_pl->viewx = pl->viewx; @@ -816,7 +826,16 @@ void R_SetTiltedSpan(INT32 span) static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff) { R_SetTiltedSpan(y); - R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); + + if (pl->xscale != FRACUNIT || pl->yscale != FRACUNIT) + { + R_SetScaledSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, + FixedDiv(FRACUNIT, pl->xscale), FixedDiv(FRACUNIT, pl->yscale), + xoff, yoff, pl->viewangle, pl->plangle); + } + else + R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); + R_CalculateSlopeVectors(); } diff --git a/src/r_plane.h b/src/r_plane.h index 831d4a6e1..344e71830 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -49,6 +49,7 @@ typedef struct visplane_s INT32 high, low; // R_PlaneBounds should set these. fixed_t xoffs, yoffs; // Scrolling flats. + fixed_t xscale, yscale; struct ffloor_s *ffloor; polyobj_t *polyobj; From 6f4d1b43ea06ecfd0c71cb2cdb9a482c449d4dc1 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 02:11:59 -0300 Subject: [PATCH 42/85] Fix scaling of walls that are skewed by a slope --- src/r_segs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 8a8827c10..a8fe4deb5 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1822,13 +1822,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) else if (linedef->flags & ML_DONTPEGBOTTOM) { rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight; - rw_midtextureslide = FixedMul(floorfrontslide, rw_midtexturescaley); + rw_midtextureslide = floorfrontslide; } else { // top of texture at top rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley); - rw_midtextureslide = FixedMul(ceilingfrontslide, rw_midtexturescaley); + rw_midtextureslide = ceilingfrontslide; } } else @@ -1846,13 +1846,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) else if (linedef->flags & ML_DONTPEGBOTTOM) { rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley); - rw_midtextureslide = FixedMul(floorfrontslide, rw_midtexturescaley); + rw_midtextureslide = floorfrontslide; } else { // top of texture at top rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight; - rw_midtextureslide = FixedMul(ceilingfrontslide, rw_midtexturescaley); + rw_midtextureslide = ceilingfrontslide; } } From 3764ba3de0aa96f573d1597cebf0578b725f7a18 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 02:17:59 -0300 Subject: [PATCH 43/85] Sector texture scaling, part 2 --- src/hardware/hw_main.c | 48 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3a347196d..369f731b2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -458,14 +458,18 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight; + fflatwidth /= FixedToFloat(FOFsector->floorxscale); + fflatheight /= FixedToFloat(FOFsector->flooryscale); + scrollx = FixedToFloat(FOFsector->floorxoffset) / fflatwidth; + scrolly = FixedToFloat(FOFsector->flooryoffset) / fflatheight; angle = FOFsector->floorangle; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight; + fflatwidth /= FixedToFloat(FOFsector->ceilingxscale); + fflatheight /= FixedToFloat(FOFsector->ceilingyscale); + scrollx = FixedToFloat(FOFsector->ceilingxoffset) / fflatwidth; + scrolly = FixedToFloat(FOFsector->ceilingyoffset) / fflatheight; angle = FOFsector->ceilingangle; } } @@ -473,14 +477,18 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight; + fflatwidth /= FixedToFloat(gl_frontsector->floorxscale); + fflatheight /= FixedToFloat(gl_frontsector->flooryscale); + scrollx = FixedToFloat(gl_frontsector->floorxoffset) / fflatwidth; + scrolly = FixedToFloat(gl_frontsector->flooryoffset) / fflatheight; angle = gl_frontsector->floorangle; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight; + fflatwidth /= FixedToFloat(gl_frontsector->ceilingxscale); + fflatheight /= FixedToFloat(gl_frontsector->ceilingyscale); + scrollx = FixedToFloat(gl_frontsector->ceilingxoffset) / fflatwidth; + scrolly = FixedToFloat(gl_frontsector->ceilingyoffset) / fflatheight; angle = gl_frontsector->ceilingangle; } } @@ -2705,14 +2713,18 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight; + fflatwidth /= FixedToFloat(FOFsector->floorxscale); + fflatheight /= FixedToFloat(FOFsector->flooryscale); + scrollx = FixedToFloat(FOFsector->floorxoffset) / fflatwidth; + scrolly = FixedToFloat(FOFsector->flooryoffset) / fflatheight; angle = FOFsector->floorangle; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight; + fflatwidth /= FixedToFloat(FOFsector->ceilingxscale); + fflatheight /= FixedToFloat(FOFsector->ceilingyscale); + scrollx = FixedToFloat(FOFsector->ceilingxoffset) / fflatwidth; + scrolly = FixedToFloat(FOFsector->ceilingyoffset) / fflatheight; angle = FOFsector->ceilingangle; } } @@ -2720,14 +2732,18 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight; + fflatwidth /= FixedToFloat(gl_frontsector->floorxscale); + fflatheight /= FixedToFloat(gl_frontsector->flooryscale); + scrollx = FixedToFloat(gl_frontsector->floorxoffset) / fflatwidth; + scrolly = FixedToFloat(gl_frontsector->flooryoffset) / fflatheight; angle = gl_frontsector->floorangle; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight; + fflatwidth /= FixedToFloat(gl_frontsector->ceilingxscale); + fflatheight /= FixedToFloat(gl_frontsector->ceilingyscale); + scrollx = FixedToFloat(gl_frontsector->ceilingxoffset) / fflatwidth; + scrolly = FixedToFloat(gl_frontsector->ceilingyoffset) / fflatheight; angle = gl_frontsector->ceilingangle; } } From b1d7f59feada351f6e64e5cd3c6eccefcc928fa5 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 08:34:51 -0300 Subject: [PATCH 44/85] Delete cachedheight, cacheddistance, cachedxstep and cachedystep --- src/r_plane.c | 53 ++++++++++++-------------------------------------- src/r_plane.h | 4 ---- src/r_splats.c | 34 +++++++++----------------------- 3 files changed, 21 insertions(+), 70 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 786ca440c..d8d66a989 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -83,11 +83,6 @@ static fixed_t planeheight; fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t *yslope; -fixed_t cachedheight[MAXVIDHEIGHT]; -fixed_t cacheddistance[MAXVIDHEIGHT]; -fixed_t cachedxstep[MAXVIDHEIGHT]; -fixed_t cachedystep[MAXVIDHEIGHT]; - static fixed_t xoffs, yoffs; static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v; @@ -159,31 +154,20 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) planecos = FINECOSINE(angle); planesin = FINESINE(angle); - if (planeheight != cachedheight[y]) + // [RH] Notice that I dumped the caching scheme used by Doom. + // It did not offer any appreciable speedup. + distance = FixedMul(planeheight, yslope[y]); + span = abs(centery - y); + + if (span) // Don't divide by zero { - cachedheight[y] = planeheight; - cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]); - span = abs(centery - y); - - if (span) // Don't divide by zero - { - ds_xstep = FixedMul(planesin, planeheight) / span; - ds_ystep = FixedMul(planecos, planeheight) / span; - ds_xstep = FixedMul(currentplane->xscale, ds_xstep); - ds_ystep = FixedMul(currentplane->yscale, ds_ystep); - } - else - ds_xstep = ds_ystep = FRACUNIT; - - cachedxstep[y] = ds_xstep; - cachedystep[y] = ds_ystep; + ds_xstep = FixedMul(planesin, planeheight) / span; + ds_ystep = FixedMul(planecos, planeheight) / span; + ds_xstep = FixedMul(currentplane->xscale, ds_xstep); + ds_ystep = FixedMul(currentplane->yscale, ds_ystep); } else - { - distance = cacheddistance[y]; - ds_xstep = cachedxstep[y]; - ds_ystep = cachedystep[y]; - } + ds_xstep = ds_ystep = FRACUNIT; // [RH] Instead of using the xtoviewangle array, I calculated the fractional values // at the middle of the screen, then used the calculated ds_xstep and ds_ystep @@ -277,10 +261,7 @@ static void R_MapFogPlane(INT32 y, INT32 x1, INT32 x2) if (x1 >= vid.width) x1 = vid.width - 1; - if (planeheight != cachedheight[y]) - distance = FixedMul(planeheight, yslope[y]); - else - distance = cacheddistance[y]; + distance = FixedMul(planeheight, yslope[y]); pindex = distance >> LIGHTZSHIFT; if (pindex >= MAXLIGHTZ) @@ -363,9 +344,6 @@ void R_ClearPlanes(void) { freehead = &(*freehead)->next; } - - // texture calculation - memset(cachedheight, 0, sizeof (cachedheight)); } static visplane_t *new_visplane(unsigned hash) @@ -1023,13 +1001,6 @@ void R_DrawSinglePlane(visplane_t *pl) } } - // Don't mess with angle on slopes! We'll handle this ourselves later - if (!pl->slope && viewangle != pl->viewangle+pl->plangle) - { - memset(cachedheight, 0, sizeof (cachedheight)); - viewangle = pl->viewangle+pl->plangle; - } - mapfunc = R_MapPlane; if (ds_solidcolor) diff --git a/src/r_plane.h b/src/r_plane.h index 344e71830..38d49d5db 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -63,10 +63,6 @@ extern visplane_t *ceilingplane; // Visplane related. extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; -extern fixed_t cachedheight[MAXVIDHEIGHT]; -extern fixed_t cacheddistance[MAXVIDHEIGHT]; -extern fixed_t cachedxstep[MAXVIDHEIGHT]; -extern fixed_t cachedystep[MAXVIDHEIGHT]; extern fixed_t *yslope; extern lighttable_t **planezlight; diff --git a/src/r_splats.c b/src/r_splats.c index 0b482d798..9bfaa6b51 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -391,8 +391,6 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (pSplat->angle) { - memset(cachedheight, 0, sizeof(cachedheight)); - // Add the view offset, rotated by the plane angle. fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x; fixed_t b = -pSplat->verts[0].y + vis->viewpoint.y; @@ -547,29 +545,18 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr angle_t planecos = FINECOSINE(angle); angle_t planesin = FINESINE(angle); - if (planeheight != cachedheight[y]) + // [RH] Notice that I dumped the caching scheme used by Doom. + // It did not offer any appreciable speedup. + distance = FixedMul(planeheight, yslope[y]); + span = abs(centery - y); + + if (span) // Don't divide by zero { - cachedheight[y] = planeheight; - distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]); - span = abs(centery - y); - - if (span) // Don't divide by zero - { - xstep = FixedMul(planesin, planeheight) / span; - ystep = FixedMul(planecos, planeheight) / span; - } - else - xstep = ystep = FRACUNIT; - - cachedxstep[y] = xstep; - cachedystep[y] = ystep; + xstep = FixedMul(planesin, planeheight) / span; + ystep = FixedMul(planecos, planeheight) / span; } else - { - distance = cacheddistance[y]; - xstep = cachedxstep[y]; - ystep = cachedystep[y]; - } + xstep = ystep = FRACUNIT; ds_xstep = FixedDiv(xstep, pSplat->xscale); ds_ystep = FixedDiv(ystep, pSplat->yscale); @@ -586,9 +573,6 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr rastertab[y].minx = INT32_MAX; rastertab[y].maxx = INT32_MIN; } - - if (!ds_solidcolor && pSplat->angle && !pSplat->slope) - memset(cachedheight, 0, sizeof(cachedheight)); } static void prepare_rastertab(void) From c5de9bdb7d64663cb9e83b2d9db998d21e9429e0 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 08:47:59 -0300 Subject: [PATCH 45/85] Add ffloor xoffs, yoffs, xscale, yscale to Lua --- src/lua_maplib.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index aca07b1c3..2037dc28c 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -267,8 +267,16 @@ enum ffloor_e { ffloor_topheight, ffloor_toppic, ffloor_toplightlevel, + ffloor_topxoffs, + ffloor_topyoffs, + ffloor_topxscale, + ffloor_topyscale, ffloor_bottomheight, ffloor_bottompic, + ffloor_bottomxoffs, + ffloor_bottomyoffs, + ffloor_bottomxscale, + ffloor_bottomyscale, ffloor_tslope, ffloor_bslope, ffloor_sector, @@ -293,8 +301,16 @@ static const char *const ffloor_opt[] = { "topheight", "toppic", "toplightlevel", + "topxoffs", + "topyoffs", + "topxscale", + "topyscale", "bottomheight", "bottompic", + "bottomxoffs", + "bottomyoffs", + "bottomxscale", + "bottomyscale", "t_slope", "b_slope", "sector", // secnum pushed as control sector userdata @@ -2182,6 +2198,18 @@ static int ffloor_get(lua_State *L) case ffloor_toplightlevel: lua_pushinteger(L, *ffloor->toplightlevel); return 1; + case ffloor_topxoffs: + lua_pushfixed(L, *ffloor->topxoffs); + return 1; + case ffloor_topyoffs: + lua_pushfixed(L, *ffloor->topyoffs); + return 1; + case ffloor_topxscale: + lua_pushfixed(L, *ffloor->topxscale); + return 1; + case ffloor_topyscale: + lua_pushfixed(L, *ffloor->topyscale); + return 1; case ffloor_bottomheight: lua_pushfixed(L, *ffloor->bottomheight); return 1; @@ -2193,6 +2221,18 @@ static int ffloor_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } + case ffloor_bottomxoffs: + lua_pushfixed(L, *ffloor->bottomxoffs); + return 1; + case ffloor_bottomyoffs: + lua_pushfixed(L, *ffloor->bottomyoffs); + return 1; + case ffloor_bottomxscale: + lua_pushfixed(L, *ffloor->bottomxscale); + return 1; + case ffloor_bottomyscale: + lua_pushfixed(L, *ffloor->bottomyscale); + return 1; case ffloor_tslope: LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE); return 1; @@ -2377,6 +2417,18 @@ static int ffloor_set(lua_State *L) case ffloor_toplightlevel: *ffloor->toplightlevel = (INT16)luaL_checkinteger(L, 3); break; + case ffloor_topxoffs: + *ffloor->topxoffs = luaL_checkfixed(L, 3); + break; + case ffloor_topyoffs: + *ffloor->topyoffs = luaL_checkfixed(L, 3); + break; + case ffloor_topxscale: + *ffloor->topxscale = luaL_checkfixed(L, 3); + break; + case ffloor_topyscale: + *ffloor->topyscale = luaL_checkfixed(L, 3); + break; case ffloor_bottomheight: { // bottomheight boolean flag; fixed_t lastpos = *ffloor->bottomheight; @@ -2395,6 +2447,18 @@ static int ffloor_set(lua_State *L) case ffloor_bottompic: *ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; + case ffloor_bottomxoffs: + *ffloor->bottomxoffs = luaL_checkfixed(L, 3); + break; + case ffloor_bottomyoffs: + *ffloor->bottomyoffs = luaL_checkfixed(L, 3); + break; + case ffloor_bottomxscale: + *ffloor->bottomxscale = luaL_checkfixed(L, 3); + break; + case ffloor_bottomyscale: + *ffloor->bottomyscale = luaL_checkfixed(L, 3); + break; case ffloor_fofflags: { ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags ffloor->fofflags = luaL_checkinteger(L, 3); From b411b9e5235eb3a21a9f7d2531a91a48721e0087 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 12:28:53 -0300 Subject: [PATCH 46/85] Fix potential misalignment with scaled slope textures --- src/r_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_plane.c b/src/r_plane.c index d8d66a989..d9dccd89c 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -1037,7 +1037,7 @@ void R_DrawSinglePlane(visplane_t *pl) { mapfunc = R_MapTiltedPlane; - if (!pl->plangle && !ds_solidcolor) + if (!pl->plangle && !ds_solidcolor && pl->xscale == FRACUNIT && pl->yscale == FRACUNIT) { if (ds_powersoftwo) R_AdjustSlopeCoordinates(&pl->slope->o); From 89770d98217fe7eb1b235301285c359ce28fd42c Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 13:44:20 -0300 Subject: [PATCH 47/85] Make sector texture offsets not scale --- src/hardware/hw_main.c | 76 +++++++++++++++++++----------------------- src/r_plane.c | 12 ++----- 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 369f731b2..34e6dc777 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -373,8 +373,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool INT32 i; float height; // constant y for all points on the convex flat polygon - float flatxref, flatyref, anglef = 0.0f; + float anglef = 0.0f; float fflatwidth = 64.0f, fflatheight = 64.0f; + float xscale, yscale; float tempxsow, tempytow; float scrollx = 0.0f, scrolly = 0.0f; @@ -409,11 +410,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool slope = gl_frontsector->c_slope; } - // Set fixedheight to the slope's height from our viewpoint, if we have a slope - if (slope) - fixedheight = P_GetSlopeZAt(slope, viewx, viewy); - - height = FIXED_TO_FLOAT(fixedheight); + height = FixedToFloat(fixedheight); // Allocate plane-vertex buffer if we need to if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) @@ -449,25 +446,21 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool else // set no texture HWR_SetCurrentTexture(NULL); - // reference point for flat texture coord for each vertex around the polygon - flatxref = 0.0; - flatyref = 0.0; - // transform if (FOFsector != NULL) { if (!isceiling) // it's a floor { - fflatwidth /= FixedToFloat(FOFsector->floorxscale); - fflatheight /= FixedToFloat(FOFsector->flooryscale); + xscale = FixedToFloat(FOFsector->floorxscale); + yscale = FixedToFloat(FOFsector->flooryscale); scrollx = FixedToFloat(FOFsector->floorxoffset) / fflatwidth; scrolly = FixedToFloat(FOFsector->flooryoffset) / fflatheight; angle = FOFsector->floorangle; } else // it's a ceiling { - fflatwidth /= FixedToFloat(FOFsector->ceilingxscale); - fflatheight /= FixedToFloat(FOFsector->ceilingyscale); + xscale = FixedToFloat(FOFsector->ceilingxscale); + yscale = FixedToFloat(FOFsector->ceilingyscale); scrollx = FixedToFloat(FOFsector->ceilingxoffset) / fflatwidth; scrolly = FixedToFloat(FOFsector->ceilingyoffset) / fflatheight; angle = FOFsector->ceilingangle; @@ -477,16 +470,16 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool { if (!isceiling) // it's a floor { - fflatwidth /= FixedToFloat(gl_frontsector->floorxscale); - fflatheight /= FixedToFloat(gl_frontsector->flooryscale); + xscale = FixedToFloat(gl_frontsector->floorxscale); + yscale = FixedToFloat(gl_frontsector->flooryscale); scrollx = FixedToFloat(gl_frontsector->floorxoffset) / fflatwidth; scrolly = FixedToFloat(gl_frontsector->flooryoffset) / fflatheight; angle = gl_frontsector->floorangle; } else // it's a ceiling { - fflatwidth /= FixedToFloat(gl_frontsector->ceilingxscale); - fflatheight /= FixedToFloat(gl_frontsector->ceilingyscale); + xscale = FixedToFloat(gl_frontsector->ceilingxscale); + yscale = FixedToFloat(gl_frontsector->ceilingyscale); scrollx = FixedToFloat(gl_frontsector->ceilingxoffset) / fflatwidth; scrolly = FixedToFloat(gl_frontsector->ceilingyoffset) / fflatheight; angle = gl_frontsector->ceilingangle; @@ -497,8 +490,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool #define SETUP3DVERT(vert, vx, vy) {\ /* Hurdler: add scrolling texture on floor/ceiling */\ - vert->s = (float)(((vx) / fflatwidth) - flatxref + scrollx);\ - vert->t = (float)(flatyref - ((vy) / fflatheight) + scrolly);\ + vert->s = ((vx) / fflatwidth) + (scrollx / xscale);\ + vert->t = -((vy) / fflatheight) + (scrolly / yscale);\ \ /* Need to rotate before translate */\ if (angle) /* Only needs to be done if there's an altered angle */\ @@ -509,15 +502,18 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool vert->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));\ }\ \ - vert->x = (vx);\ - vert->y = height;\ - vert->z = (vy);\ + vert->s *= xscale;\ + vert->t *= yscale;\ \ if (slope)\ {\ - fixedheight = P_GetSlopeZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ - vert->y = FIXED_TO_FLOAT(fixedheight);\ + fixedheight = P_GetSlopeZAt(slope, FloatToFixed((vx)), FloatToFixed((vy)));\ + height = FixedToFloat(fixedheight);\ }\ +\ + vert->x = (vx);\ + vert->y = height;\ + vert->z = (vy);\ } for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++,v3d++,pv++) @@ -2649,8 +2645,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, INT32 i; float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon - float flatxref, flatyref; float fflatwidth = 64.0f, fflatheight = 64.0f; + float xscale, yscale; float scrollx = 0.0f, scrolly = 0.0f; float tempxsow, tempytow, anglef = 0.0f; @@ -2701,11 +2697,6 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, else // set no texture HWR_SetCurrentTexture(NULL); - // reference point for flat texture coord for each vertex around the polygon - flatxref = 0.0; - flatyref = 0.0; - - // transform v3d = planeVerts; @@ -2713,16 +2704,16 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - fflatwidth /= FixedToFloat(FOFsector->floorxscale); - fflatheight /= FixedToFloat(FOFsector->flooryscale); + xscale = FixedToFloat(FOFsector->floorxscale); + yscale = FixedToFloat(FOFsector->flooryscale); scrollx = FixedToFloat(FOFsector->floorxoffset) / fflatwidth; scrolly = FixedToFloat(FOFsector->flooryoffset) / fflatheight; angle = FOFsector->floorangle; } else // it's a ceiling { - fflatwidth /= FixedToFloat(FOFsector->ceilingxscale); - fflatheight /= FixedToFloat(FOFsector->ceilingyscale); + xscale = FixedToFloat(FOFsector->ceilingxscale); + yscale = FixedToFloat(FOFsector->ceilingyscale); scrollx = FixedToFloat(FOFsector->ceilingxoffset) / fflatwidth; scrolly = FixedToFloat(FOFsector->ceilingyoffset) / fflatheight; angle = FOFsector->ceilingangle; @@ -2732,16 +2723,16 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - fflatwidth /= FixedToFloat(gl_frontsector->floorxscale); - fflatheight /= FixedToFloat(gl_frontsector->flooryscale); + xscale = FixedToFloat(gl_frontsector->floorxscale); + yscale = FixedToFloat(gl_frontsector->flooryscale); scrollx = FixedToFloat(gl_frontsector->floorxoffset) / fflatwidth; scrolly = FixedToFloat(gl_frontsector->flooryoffset) / fflatheight; angle = gl_frontsector->floorangle; } else // it's a ceiling { - fflatwidth /= FixedToFloat(gl_frontsector->ceilingxscale); - fflatheight /= FixedToFloat(gl_frontsector->ceilingyscale); + xscale = FixedToFloat(gl_frontsector->ceilingxscale); + yscale = FixedToFloat(gl_frontsector->ceilingyscale); scrollx = FixedToFloat(gl_frontsector->ceilingxoffset) / fflatwidth; scrolly = FixedToFloat(gl_frontsector->ceilingyoffset) / fflatheight; angle = gl_frontsector->ceilingangle; @@ -2754,8 +2745,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { // Go from the polysector's original vertex locations // Means the flat is offset based on the original vertex locations - v3d->s = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); - v3d->t = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); + v3d->s = (FixedToFloat(polysector->origVerts[i].x) / fflatwidth) + (scrollx / xscale); + v3d->t = -(FixedToFloat(polysector->origVerts[i].y) / fflatheight) + (scrolly / yscale); // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle @@ -2767,6 +2758,9 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, v3d->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef)); } + v3d->s *= xscale; + v3d->t *= yscale; + v3d->x = FIXED_TO_FLOAT(polysector->vertices[i]->x); v3d->y = height; v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y); diff --git a/src/r_plane.c b/src/r_plane.c index d9dccd89c..9c87ecbe4 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -380,8 +380,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, if (!slope) // Don't mess with this right now if a slope is involved { - xoff += viewx; - yoff -= viewy; + xoff += FixedMul(viewx, xscale); + yoff -= FixedMul(viewy, yscale); if (plangle != 0) { @@ -411,12 +411,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } - if (!slope) - { - xoff = FixedMul(xoff, xscale); - yoff = FixedMul(yoff, yscale); - } - // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) { @@ -809,7 +803,7 @@ static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_ { R_SetScaledSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, FixedDiv(FRACUNIT, pl->xscale), FixedDiv(FRACUNIT, pl->yscale), - xoff, yoff, pl->viewangle, pl->plangle); + FixedDiv(xoff, pl->xscale), FixedDiv(yoff, pl->yscale), pl->viewangle, pl->plangle); } else R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); From 6948537e9e410b1a434e5e3f1c41b1259ba93bdd Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 13:49:44 -0300 Subject: [PATCH 48/85] Initialize xscale and yscale --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 34e6dc777..ad6ed327c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -375,7 +375,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool float height; // constant y for all points on the convex flat polygon float anglef = 0.0f; float fflatwidth = 64.0f, fflatheight = 64.0f; - float xscale, yscale; + float xscale = 1.0f, yscale = 1.0f; float tempxsow, tempytow; float scrollx = 0.0f, scrolly = 0.0f; @@ -2646,7 +2646,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon float fflatwidth = 64.0f, fflatheight = 64.0f; - float xscale, yscale; + float xscale = 1.0f, yscale = 1.0f; float scrollx = 0.0f, scrolly = 0.0f; float tempxsow, tempytow, anglef = 0.0f; From 6596fc97acbf32f0db270e796d3ef58a76afdb38 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 13:54:09 -0300 Subject: [PATCH 49/85] Accept '_bottom' instead of just '_bot' to match the UDMF names --- src/lua_maplib.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 2037dc28c..78b07baaf 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -194,13 +194,17 @@ enum side_e { side_offsety_top, side_offsetx_mid, side_offsety_mid, + side_offsetx_bottom, side_offsetx_bot, + side_offsety_bottom, side_offsety_bot, side_scalex_top, side_scaley_top, side_scalex_mid, side_scaley_mid, + side_scalex_bottom, side_scalex_bot, + side_scaley_bottom, side_scaley_bot, side_toptexture, side_bottomtexture, @@ -220,13 +224,17 @@ static const char *const side_opt[] = { "offsety_top", "offsetx_mid", "offsety_mid", + "offsetx_bottom", "offsetx_bot", + "offsety_bottom", "offsety_bot", "scalex_top", "scaley_top", "scalex_mid", "scaley_mid", + "scalex_bottom", "scalex_bot", + "scaley_bottom", "scaley_bot", "toptexture", "bottomtexture", @@ -1253,9 +1261,11 @@ static int side_get(lua_State *L) case side_offsety_mid: lua_pushfixed(L, side->offsety_mid); return 1; + case side_offsetx_bottom: case side_offsetx_bot: lua_pushfixed(L, side->offsetx_bottom); return 1; + case side_offsety_bottom: case side_offsety_bot: lua_pushfixed(L, side->offsety_bottom); return 1; @@ -1271,9 +1281,11 @@ static int side_get(lua_State *L) case side_scaley_mid: lua_pushfixed(L, side->scaley_mid); return 1; + case side_scalex_bottom: case side_scalex_bot: lua_pushfixed(L, side->scalex_bottom); return 1; + case side_scaley_bottom: case side_scaley_bot: lua_pushfixed(L, side->scaley_bottom); return 1; From 147d5948fc5f3a8fb18fcb097b0a96eaca7a7bf3 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 24 Nov 2023 13:56:56 -0300 Subject: [PATCH 50/85] Remove 'scalex_bot' and 'scaley_bot' --- src/lua_maplib.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 78b07baaf..0efce3114 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -203,9 +203,7 @@ enum side_e { side_scalex_mid, side_scaley_mid, side_scalex_bottom, - side_scalex_bot, side_scaley_bottom, - side_scaley_bot, side_toptexture, side_bottomtexture, side_midtexture, @@ -1282,11 +1280,9 @@ static int side_get(lua_State *L) lua_pushfixed(L, side->scaley_mid); return 1; case side_scalex_bottom: - case side_scalex_bot: lua_pushfixed(L, side->scalex_bottom); return 1; case side_scaley_bottom: - case side_scaley_bot: lua_pushfixed(L, side->scaley_bottom); return 1; case side_toptexture: @@ -1372,9 +1368,11 @@ static int side_set(lua_State *L) side->offsety_mid = luaL_checkfixed(L, 3); break; case side_offsetx_bot: + case side_offsetx_bottom: side->offsetx_bottom = luaL_checkfixed(L, 3); break; case side_offsety_bot: + case side_offsety_bottom: side->offsety_bottom = luaL_checkfixed(L, 3); break; case side_scalex_top: @@ -1389,10 +1387,10 @@ static int side_set(lua_State *L) case side_scaley_mid: side->scaley_mid = luaL_checkfixed(L, 3); break; - case side_scalex_bot: + case side_scalex_bottom: side->scalex_bottom = luaL_checkfixed(L, 3); break; - case side_scaley_bot: + case side_scaley_bottom: side->scaley_bottom = luaL_checkfixed(L, 3); break; case side_toptexture: From 3f98755c11bc36cbb735c427f41441878f873d33 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sat, 25 Nov 2023 15:19:48 -0300 Subject: [PATCH 51/85] Actually remove 'scalex_bot' and 'scaley_bot' --- src/lua_maplib.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 0efce3114..0b998199b 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -231,9 +231,7 @@ static const char *const side_opt[] = { "scalex_mid", "scaley_mid", "scalex_bottom", - "scalex_bot", "scaley_bottom", - "scaley_bot", "toptexture", "bottomtexture", "midtexture", From 87d99fe84ccaa9bb18821b49819dfbd19541fe89 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 26 Nov 2023 03:56:19 -0300 Subject: [PATCH 52/85] Fix scaling of walls that are skewed by a slope, part 2 --- src/r_segs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index a8fe4deb5..6085bae7c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2082,7 +2082,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley); - rw_toptextureslide = FixedMul(rw_toptextureslide, rw_toptexturescaley); } // check BOTTOM TEXTURE @@ -2123,7 +2122,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley); - rw_bottomtextureslide = FixedMul(rw_bottomtextureslide, rw_bottomtexturescaley); } rw_toptexturemid += toprowoffset; From 40f57de187896d241f67e810f859c3c7f431e102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 26 Nov 2023 21:30:54 +0100 Subject: [PATCH 53/85] Add indicator for IPv6-enabled servers --- src/m_menu.c | 2 ++ src/netcode/d_net.h | 1 + src/netcode/i_tcp.c | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index 629f53d24..e863bc40f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -11254,6 +11254,8 @@ static void M_DrawConnectMenu(void) V_DrawSmallString(currentMenu->x+202, S_LINEY(i)+8, globalflags, "\x85" "Mod"); if (serverlist[slindex].info.cheatsenabled) V_DrawSmallString(currentMenu->x+222, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); + if (Net_IsNodeIPv6(serverlist[slindex].node)) + V_DrawSmallString(currentMenu->x+252, S_LINEY(i)+8, globalflags, "\x84" "IPv6"); V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags, va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); diff --git a/src/netcode/d_net.h b/src/netcode/d_net.h index 549f2b93c..2f83939f8 100644 --- a/src/netcode/d_net.h +++ b/src/netcode/d_net.h @@ -70,6 +70,7 @@ boolean HGetPacket(void); void D_SetDoomcom(void); boolean D_CheckNetGame(void); void D_CloseConnection(void); +boolean Net_IsNodeIPv6(INT32 node); void Net_UnAcknowledgePacket(INT32 node); void Net_CloseConnection(INT32 node); void Net_ConnectionTimeout(INT32 node); diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index 0b650de49..b6d7724a4 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -1362,4 +1362,9 @@ boolean I_InitTcpNetwork(void) return ret; } +boolean Net_IsNodeIPv6(INT32 node) +{ + return clientaddress[node].any.sa_family == AF_INET6; +} + #include "i_addrinfo.c" From b5c8db00f836f303ca33319f73969f6226474059 Mon Sep 17 00:00:00 2001 From: LoganAir Date: Sun, 26 Nov 2023 17:44:03 -0500 Subject: [PATCH 54/85] Update mserv.c https://mb.srb2.org is now behind CloudFlare, and the Master Server API v1 can not be accessed for some users due to this change. so I setup a new dual stack DNS record for accessing to the API --- src/mserv.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/mserv.c b/src/mserv.c index 62cda96e4..f83b16d07 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -61,7 +61,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { {0,NULL} }; -consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); +consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters); consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters); @@ -544,6 +544,13 @@ static void MasterServer_OnChange(void) CV_StealthSet(&cv_masterserver, cv_masterserver.defaultvalue); } + if ( + ! cv_masterserver.changed && + strcmp(cv_masterserver.string, "https://mb.srb2.org/MS/0") == 0 + ){ + CV_StealthSet(&cv_masterserver, cv_masterserver.defaultvalue); + } + Set_api(cv_masterserver.string); if (Online()) From 2e885d4e6fd69b66c1c5cfd2a973f2353f0840ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 30 Nov 2023 16:03:44 +0100 Subject: [PATCH 55/85] Add NO_IPV6 check --- src/netcode/i_tcp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index b6d7724a4..c70290e54 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -1364,7 +1364,11 @@ boolean I_InitTcpNetwork(void) boolean Net_IsNodeIPv6(INT32 node) { +#ifdef NO_IPV6 + return false; +#else return clientaddress[node].any.sa_family == AF_INET6; +#endif } #include "i_addrinfo.c" From ff492cbdcc0b5e76cff62cf23798c856945dfafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 30 Nov 2023 16:29:08 +0100 Subject: [PATCH 56/85] Register both IPv4 and IPv6 on the master server --- src/netcode/http-mserv.c | 90 +++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 10 deletions(-) diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index f8bd5da21..10137e67b 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -35,6 +35,10 @@ Documentation available here. #define Blame( ... ) \ CONS_Printf("\x85" __VA_ARGS__) +#define PROTO_ANY 0 +#define PROTO_V4 1 +#define PROTO_V6 2 + static void MasterServer_Debug_OnChange (void); consvar_t cv_masterserver_timeout = CVAR_INIT @@ -59,12 +63,17 @@ consvar_t cv_masterserver_token = CVAR_INIT static int hms_started; +static boolean hms_allow_ipv6; + static char *hms_api; #ifdef HAVE_THREADS static I_mutex hms_api_mutex; #endif static char *hms_server_token; +#ifndef NO_IPV6 +static char *hms_server_token_ipv6; +#endif static char hms_useragent[512]; @@ -126,7 +135,7 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata) } static struct HMS_buffer * -HMS_connect (const char *format, ...) +HMS_connect (int proto, const char *format, ...) { va_list ap; CURL *curl; @@ -136,8 +145,14 @@ HMS_connect (const char *format, ...) size_t token_length; struct HMS_buffer *buffer; +#ifdef NO_IPV6 + if (proto == PROTO_V6) + return NULL; +#endif + if (! hms_started) { + hms_allow_ipv6 = !M_CheckParm("-noipv6"); if (curl_global_init(CURL_GLOBAL_ALL) != 0) { Contact_error(); @@ -219,7 +234,9 @@ HMS_connect (const char *format, ...) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); #ifndef NO_IPV6 - if (M_CheckParm("-noipv6")) + if (proto == PROTO_V6) + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); + if (proto == PROTO_V4) #endif curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); @@ -309,7 +326,7 @@ HMS_fetch_rooms (int joining, int query_id) (void)query_id; - hms = HMS_connect("rooms"); + hms = HMS_connect(PROTO_ANY, "rooms"); if (! hms) return 0; @@ -409,7 +426,7 @@ HMS_register (void) char *title; - hms = HMS_connect("rooms/%d/register", ms_RoomId); + hms = HMS_connect(PROTO_V4, "rooms/%d/register", ms_RoomId); if (! hms) return 0; @@ -441,6 +458,27 @@ HMS_register (void) HMS_end(hms); +#ifndef NO_IPV6 + if (!hms_allow_ipv6) + return ok; + + hms = HMS_connect(PROTO_V6, "rooms/%d/register", ms_RoomId); + + if (! hms) + return 0; + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + + if (ok) + { + hms_server_token_ipv6 = strdup(strtok(hms->buffer, "\n")); + } + + HMS_end(hms); +#endif + return ok; } @@ -450,7 +488,7 @@ HMS_unlist (void) struct HMS_buffer *hms; int ok; - hms = HMS_connect("servers/%s/unlist", hms_server_token); + hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token); if (! hms) return 0; @@ -462,6 +500,23 @@ HMS_unlist (void) free(hms_server_token); +#ifndef NO_IPV6 + if (hms_server_token_ipv6 && hms_allow_ipv6) + { + hms = HMS_connect(PROTO_V6, "servers/%s/unlist", hms_server_token_ipv6); + + if (! hms) + return 0; + + curl_easy_setopt(hms->curl, CURLOPT_CUSTOMREQUEST, "POST"); + + ok = HMS_do(hms); + HMS_end(hms); + + free(hms_server_token_ipv6); + } +#endif + return ok; } @@ -475,7 +530,7 @@ HMS_update (void) char *title; - hms = HMS_connect("servers/%s/update", hms_server_token); + hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token); if (! hms) return 0; @@ -494,6 +549,21 @@ HMS_update (void) ok = HMS_do(hms); HMS_end(hms); +#ifndef NO_IPV6 + if (hms_server_token_ipv6 && hms_allow_ipv6) + { + hms = HMS_connect(PROTO_V6, "servers/%s/update", hms_server_token_ipv6); + + if (! hms) + return ok; + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + HMS_end(hms); + } +#endif + return ok; } @@ -505,7 +575,7 @@ HMS_list_servers (void) char *list; char *p; - hms = HMS_connect("servers"); + hms = HMS_connect(PROTO_ANY, "servers"); if (! hms) return; @@ -554,10 +624,10 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id) if (room_number > 0) { - hms = HMS_connect("rooms/%d/servers", room_number); + hms = HMS_connect(PROTO_ANY, "rooms/%d/servers", room_number); } else - hms = HMS_connect("servers"); + hms = HMS_connect(PROTO_ANY, "servers"); if (! hms) return NULL; @@ -661,7 +731,7 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size) char *version; char *version_name; - hms = HMS_connect("versions/%d", MODID); + hms = HMS_connect(PROTO_ANY, "versions/%d", MODID); if (! hms) return 0; From 244ad5b8925c201a82de323b5155776a7c173fe0 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 3 Dec 2023 00:22:23 -0300 Subject: [PATCH 57/85] Remove CPUID code --- src/doomdef.h | 2 +- src/m_misc.c | 421 +------------------------------------------------- src/screen.c | 50 ------ src/screen.h | 11 -- 4 files changed, 2 insertions(+), 482 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index b382d0ecb..4e08b11bf 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -533,7 +533,7 @@ extern char liveeventbackup[256]; #define M_GetText(x) (x) #endif void M_StartupLocale(void); -extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; +void *M_Memcpy(void* dest, const void* src, size_t n); char *va(const char *format, ...) FUNCPRINTF; char *M_GetToken(const char *inputString); void M_UnGetToken(void); diff --git a/src/m_misc.c b/src/m_misc.c index 923a188c6..ce332910d 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2207,430 +2207,11 @@ char *sizeu5(size_t num) return sizeu5_buf; } -#if defined (__GNUC__) && defined (__i386__) // from libkwave, under GPL -// Alam: note libkwave memcpy code comes from mplayer's libvo/aclib_template.c, r699 - -/* for small memory blocks (<256 bytes) this version is faster */ -#define small_memcpy(dest,src,n)\ -{\ -register unsigned long int dummy;\ -__asm__ __volatile__(\ - "cld\n\t"\ - "rep; movsb"\ - :"=&D"(dest), "=&S"(src), "=&c"(dummy)\ - :"0" (dest), "1" (src),"2" (n)\ - : "memory", "cc");\ -} -/* linux kernel __memcpy (from: /include/asm/string.h) */ -ATTRINLINE static FUNCINLINE void *__memcpy (void *dest, const void * src, size_t n) +void *M_Memcpy(void *dest, const void *src, size_t n) { - int d0, d1, d2; - - if ( n < 4 ) - { - small_memcpy(dest, src, n); - } - else - { - __asm__ __volatile__ ( - "rep ; movsl;" - "testb $2,%b4;" - "je 1f;" - "movsw;" - "1:\ttestb $1,%b4;" - "je 2f;" - "movsb;" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) dest),"2" ((long) src) - : "memory"); - } - - return dest; -} - -#define SSE_MMREG_SIZE 16 -#define MMX_MMREG_SIZE 8 - -#define MMX1_MIN_LEN 0x800 /* 2K blocks */ -#define MIN_LEN 0x40 /* 64-byte blocks */ - -/* SSE note: i tried to move 128 bytes a time instead of 64 but it -didn't make any measureable difference. i'm using 64 for the sake of -simplicity. [MF] */ -static /*FUNCTARGET("sse2")*/ void *sse_cpy(void * dest, const void * src, size_t n) -{ - void *retval = dest; - size_t i; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - "prefetchnta (%0);" - "prefetchnta 32(%0);" - "prefetchnta 64(%0);" - "prefetchnta 96(%0);" - "prefetchnta 128(%0);" - "prefetchnta 160(%0);" - "prefetchnta 192(%0);" - "prefetchnta 224(%0);" - "prefetchnta 256(%0);" - "prefetchnta 288(%0);" - : : "r" (src) ); - - if (n >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(SSE_MMREG_SIZE-1); - if (delta) - { - delta=SSE_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - if (((unsigned long)src) & 15) - /* if SRC is misaligned */ - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0);" - "prefetchnta 352(%0);" - "movups (%0), %%xmm0;" - "movups 16(%0), %%xmm1;" - "movups 32(%0), %%xmm2;" - "movups 48(%0), %%xmm3;" - "movntps %%xmm0, (%1);" - "movntps %%xmm1, 16(%1);" - "movntps %%xmm2, 32(%1);" - "movntps %%xmm3, 48(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = (const unsigned char *)src + 64; - dest = (unsigned char *)dest + 64; - } - else - /* - Only if SRC is aligned on 16-byte boundary. - It allows to use movaps instead of movups, which required data - to be aligned or a general-protection exception (#GP) is generated. - */ - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0);" - "prefetchnta 352(%0);" - "movaps (%0), %%xmm0;" - "movaps 16(%0), %%xmm1;" - "movaps 32(%0), %%xmm2;" - "movaps 48(%0), %%xmm3;" - "movntps %%xmm0, (%1);" - "movntps %%xmm1, 16(%1);" - "movntps %%xmm2, 32(%1);" - "movntps %%xmm3, 48(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence":::"memory"); - /* enables to use FPU */ - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -} - -static FUNCTARGET("mmx") void *mmx2_cpy(void *dest, const void *src, size_t n) -{ - void *retval = dest; - size_t i; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - "prefetchnta (%0);" - "prefetchnta 32(%0);" - "prefetchnta 64(%0);" - "prefetchnta 96(%0);" - "prefetchnta 128(%0);" - "prefetchnta 160(%0);" - "prefetchnta 192(%0);" - "prefetchnta 224(%0);" - "prefetchnta 256(%0);" - "prefetchnta 288(%0);" - : : "r" (src)); - - if (n >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1); - if (delta) - { - delta=MMX_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0);" - "prefetchnta 352(%0);" - "movq (%0), %%mm0;" - "movq 8(%0), %%mm1;" - "movq 16(%0), %%mm2;" - "movq 24(%0), %%mm3;" - "movq 32(%0), %%mm4;" - "movq 40(%0), %%mm5;" - "movq 48(%0), %%mm6;" - "movq 56(%0), %%mm7;" - "movntq %%mm0, (%1);" - "movntq %%mm1, 8(%1);" - "movntq %%mm2, 16(%1);" - "movntq %%mm3, 24(%1);" - "movntq %%mm4, 32(%1);" - "movntq %%mm5, 40(%1);" - "movntq %%mm6, 48(%1);" - "movntq %%mm7, 56(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence":::"memory"); - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -} - -static FUNCTARGET("mmx") void *mmx1_cpy(void *dest, const void *src, size_t n) //3DNOW -{ - void *retval = dest; - size_t i; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - "prefetch (%0);" - "prefetch 32(%0);" - "prefetch 64(%0);" - "prefetch 96(%0);" - "prefetch 128(%0);" - "prefetch 160(%0);" - "prefetch 192(%0);" - "prefetch 224(%0);" - "prefetch 256(%0);" - "prefetch 288(%0);" - : : "r" (src)); - - if (n >= MMX1_MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1); - if (delta) - { - delta=MMX_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetch 320(%0);" - "prefetch 352(%0);" - "movq (%0), %%mm0;" - "movq 8(%0), %%mm1;" - "movq 16(%0), %%mm2;" - "movq 24(%0), %%mm3;" - "movq 32(%0), %%mm4;" - "movq 40(%0), %%mm5;" - "movq 48(%0), %%mm6;" - "movq 56(%0), %%mm7;" - "movq %%mm0, (%1);" - "movq %%mm1, 8(%1);" - "movq %%mm2, 16(%1);" - "movq %%mm3, 24(%1);" - "movq %%mm4, 32(%1);" - "movq %%mm5, 40(%1);" - "movq %%mm6, 48(%1);" - "movq %%mm7, 56(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - __asm__ __volatile__ ("femms":::"memory"); // same as mmx_cpy() but with a femms - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -} -#endif - -// Alam: why? memcpy may be __cdecl/_System and our code may be not the same type -static void *cpu_cpy(void *dest, const void *src, size_t n) -{ - if (src == NULL) - { - CONS_Debug(DBG_MEMORY, "Memcpy from 0x0?!: %p %p %s\n", dest, src, sizeu1(n)); - return dest; - } - - if(dest == NULL) - { - CONS_Debug(DBG_MEMORY, "Memcpy to 0x0?!: %p %p %s\n", dest, src, sizeu1(n)); - return dest; - } - return memcpy(dest, src, n); } -static /*FUNCTARGET("mmx")*/ void *mmx_cpy(void *dest, const void *src, size_t n) -{ -#if defined (_MSC_VER) && defined (_X86_) - _asm - { - mov ecx, [n] - mov esi, [src] - mov edi, [dest] - shr ecx, 6 // mit mmx: 64bytes per iteration - jz lower_64 // if lower than 64 bytes - loop_64: // MMX transfers multiples of 64bytes - movq mm0, 0[ESI] // read sources - movq mm1, 8[ESI] - movq mm2, 16[ESI] - movq mm3, 24[ESI] - movq mm4, 32[ESI] - movq mm5, 40[ESI] - movq mm6, 48[ESI] - movq mm7, 56[ESI] - - movq 0[EDI], mm0 // write destination - movq 8[EDI], mm1 - movq 16[EDI], mm2 - movq 24[EDI], mm3 - movq 32[EDI], mm4 - movq 40[EDI], mm5 - movq 48[EDI], mm6 - movq 56[EDI], mm7 - - add esi, 64 - add edi, 64 - dec ecx - jnz loop_64 - emms // close mmx operation - lower_64:// transfer rest of buffer - mov ebx,esi - sub ebx,src - mov ecx,[n] - sub ecx,ebx - shr ecx, 3 // multiples of 8 bytes - jz lower_8 - loop_8: - movq mm0, [esi] // read source - movq [edi], mm0 // write destination - add esi, 8 - add edi, 8 - dec ecx - jnz loop_8 - emms // close mmx operation - lower_8: - mov ebx,esi - sub ebx,src - mov ecx,[n] - sub ecx,ebx - rep movsb - mov eax, [dest] // return dest - } -#elif defined (__GNUC__) && defined (__i386__) - void *retval = dest; - size_t i; - - if (n >= MMX1_MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1); - if (delta) - { - delta=MMX_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - for (; i>0; i--) - { - __asm__ __volatile__ ( - "movq (%0), %%mm0;" - "movq 8(%0), %%mm1;" - "movq 16(%0), %%mm2;" - "movq 24(%0), %%mm3;" - "movq 32(%0), %%mm4;" - "movq 40(%0), %%mm5;" - "movq 48(%0), %%mm6;" - "movq 56(%0), %%mm7;" - "movq %%mm0, (%1);" - "movq %%mm1, 8(%1);" - "movq %%mm2, 16(%1);" - "movq %%mm3, 24(%1);" - "movq %%mm4, 32(%1);" - "movq %%mm5, 40(%1);" - "movq %%mm6, 48(%1);" - "movq %%mm7, 56(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -#else - return cpu_cpy(dest, src, n); -#endif -} - -void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy; - -/** Memcpy that uses MMX, 3DNow, MMXExt or even SSE - * Do not use on overlapped memory, use memmove for that - */ -void M_SetupMemcpy(void) -{ -#if defined (__GNUC__) && defined (__i386__) - if (R_SSE2) - M_Memcpy = sse_cpy; - else if (R_MMXExt) - M_Memcpy = mmx2_cpy; - else if (R_3DNow) - M_Memcpy = mmx1_cpy; - else -#endif - if (R_MMX) - M_Memcpy = mmx_cpy; -#if 0 - M_Memcpy = cpu_cpy; -#endif -} - /** Return the appropriate message for a file error or end of file. */ const char *M_FileError(FILE *fp) diff --git a/src/screen.c b/src/screen.c index 3c50ec67e..ca59b251d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -98,14 +98,6 @@ UINT8 *scr_borderpatch; // flat used to fill the reduced view borders set at ST_ // Short and Tall sky drawer, for the current color mode void (*walldrawerfunc)(void); -boolean R_486 = false; -boolean R_586 = false; -boolean R_MMX = false; -boolean R_SSE = false; -boolean R_3DNow = false; -boolean R_MMXExt = false; -boolean R_SSE2 = false; - void SCR_SetDrawFuncs(void) { // @@ -225,48 +217,6 @@ void SCR_SetMode(void) // void SCR_Startup(void) { - const CPUInfoFlags *RCpuInfo = I_CPUInfo(); - if (!M_CheckParm("-NOCPUID") && RCpuInfo) - { -#if defined (__i386__) || defined (_M_IX86) || defined (__WATCOMC__) - R_486 = true; -#endif - if (RCpuInfo->RDTSC) - R_586 = true; - if (RCpuInfo->MMX) - R_MMX = true; - if (RCpuInfo->AMD3DNow) - R_3DNow = true; - if (RCpuInfo->MMXExt) - R_MMXExt = true; - if (RCpuInfo->SSE) - R_SSE = true; - if (RCpuInfo->SSE2) - R_SSE2 = true; - CONS_Printf("CPU Info: 486: %i, 586: %i, MMX: %i, 3DNow: %i, MMXExt: %i, SSE2: %i\n", R_486, R_586, R_MMX, R_3DNow, R_MMXExt, R_SSE2); - } - - if (M_CheckParm("-486")) - R_486 = true; - if (M_CheckParm("-586")) - R_586 = true; - if (M_CheckParm("-MMX")) - R_MMX = true; - if (M_CheckParm("-3DNow")) - R_3DNow = true; - if (M_CheckParm("-MMXExt")) - R_MMXExt = true; - - if (M_CheckParm("-SSE")) - R_SSE = true; - if (M_CheckParm("-noSSE")) - R_SSE = false; - - if (M_CheckParm("-SSE2")) - R_SSE2 = true; - - M_SetupMemcpy(); - if (dedicated) { V_Init(); diff --git a/src/screen.h b/src/screen.h index 46c1b99c6..e4c1006c3 100644 --- a/src/screen.h +++ b/src/screen.h @@ -172,17 +172,6 @@ extern void (*spanfunc)(void); extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void); extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); -// ----- -// CPUID -// ----- -extern boolean R_ASM; -extern boolean R_486; -extern boolean R_586; -extern boolean R_MMX; -extern boolean R_3DNow; -extern boolean R_MMXExt; -extern boolean R_SSE2; - // ---------------- // screen variables // ---------------- From eca16a811e8fdd82f4eb525664db964a17ec7a82 Mon Sep 17 00:00:00 2001 From: Logan-A Date: Tue, 5 Dec 2023 21:03:01 -0500 Subject: [PATCH 58/85] comptime.sh is a bash shell, so it should have eol=lf --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index c2e507352..9f0850930 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,6 +10,7 @@ /src/Make*.cfg text=auto /src/CMakeLists.txt text=auto *.mk -whitespace text=auto +/comptime.sh text eol=lf # Windows EOL *.cs -crlf -whitespace *.bat -crlf -whitespace From 5867b7355ec2d9d895a7cfd280b4f1aea5ce6073 Mon Sep 17 00:00:00 2001 From: Logan-A Date: Tue, 5 Dec 2023 22:54:59 -0500 Subject: [PATCH 59/85] add compnote support to comptime add compnote support to comptime --- comptime.bat | 7 +++++-- comptime.sh | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/comptime.bat b/comptime.bat index 0c7ea06d6..77879d5ee 100644 --- a/comptime.bat +++ b/comptime.bat @@ -1,6 +1,7 @@ @echo off set BRA=Unknown set REV=illegal +set GL1=Dummy copy nul: /b +%1\comptime.c tmp.$$$ > nul move tmp.$$$ %1\comptime.c > nul @@ -13,8 +14,9 @@ goto filwri :gitrev set GIT=%2 if "%GIT%"=="" set GIT=git -for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s -for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s +for /f "tokens=* usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s +for /f "tokens=* usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s +for /f "tokens=* usebackq" %%s in (`%GIT% log -1 --format^=%%s`) do @set GL1=%%s set REV=%REV:~0,8% goto filwri @@ -30,3 +32,4 @@ echo // by the %0 batch file >> %1\comptime.h echo // >> %1\comptime.h echo const char* compbranch = "%BRA%"; >> %1\comptime.h echo const char* comprevision = "%REV%"; >> %1\comptime.h +echo const char* compnote = "%GL1%"; >> %1\comptime.h diff --git a/comptime.sh b/comptime.sh index ce771f631..e37ba6ad7 100755 --- a/comptime.sh +++ b/comptime.sh @@ -12,24 +12,26 @@ version() { // const char* compbranch = "$1"; const char* comprevision = "$2"; +const char* compnote = "$3"; EOF } versiongit() { gitbranch="$(git rev-parse --abbrev-ref HEAD)" gitversion="$(git rev-parse HEAD | cut -c -8)" - version "$gitbranch" "$gitversion"; + gitsubject="$(git log -1 --format=%s)" + version "$gitbranch" "$gitversion" "$gitsubject"; exit 0 } versionsvn() { svnrevision="$(svnversion -n "$1")" - version "Subversion" "r$svnrevision"; + version "Subversion" "r$svnrevision" "dummy"; exit 0 } versionfake() { - version "Unknown" "illegal"; + version "Unknown" "illegal" "dummy"; } compversion() { From e1562ad4c51b9d77d25a92d5f8e45b2fdf4604bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 6 Dec 2023 17:00:27 +0100 Subject: [PATCH 60/85] Fix crash when trying to send to an unreachable client --- src/netcode/i_tcp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index 0b650de49..bde3a0e8d 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -83,6 +83,10 @@ #undef ETIMEDOUT #endif #define ETIMEDOUT WSAETIMEDOUT + #ifdef EHOSTUNREACH + #undef EHOSTUNREACH + #endif + #define EHOSTUNREACH WSAEHOSTUNREACH #ifndef IOC_VENDOR #define IOC_VENDOR 0x18000000 #endif @@ -678,7 +682,7 @@ static void SOCK_Send(void) if (c == ERRSOCKET) { int e = errno; // save error code so it can't be modified later - if (e != ECONNREFUSED && e != EWOULDBLOCK) + if (e != ECONNREFUSED && e != EWOULDBLOCK && e != EHOSTUNREACH) I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode, SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e)); } From 0131cdb03d790810445ae7a3d6947b0ab44ceeb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 14 Dec 2023 16:30:04 +0100 Subject: [PATCH 61/85] Fix IPv6 bans being ignored when loading banlist --- src/netcode/commands.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/netcode/commands.c b/src/netcode/commands.c index 4b67198ba..e7d51437e 100644 --- a/src/netcode/commands.c +++ b/src/netcode/commands.c @@ -79,7 +79,7 @@ static void Ban_Clear(void) void Ban_Load_File(boolean warning) { FILE *f; - const char *address, *mask; + char *address, *mask; char buffer[MAX_WADPATH]; if (!I_ClearBans) @@ -100,6 +100,14 @@ void Ban_Load_File(boolean warning) { address = strtok(buffer, " \t\r\n"); mask = strtok(NULL, " \t\r\n"); + if (address[0] == '[') + { + size_t len; + address++; + len = strlen(address); + if (address[len-1] == ']') + address[len-1] = '\0'; + } I_SetBanAddress(address, mask); From 59aa6fdad4f89279f5106a4be0fdc7588117c706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 14 Dec 2023 17:00:20 +0100 Subject: [PATCH 62/85] Fix ban mask being ignored on IPv6 addresses --- src/netcode/i_tcp.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index c70290e54..d91583e25 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -404,6 +404,20 @@ static const char *SOCK_GetBanMask(size_t ban) return NULL; } +#ifdef HAVE_IPV6 +static boolean SOCK_cmpipv6(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) +{ + UINT8 bitmask; + I_Assert(mask <= 128); + if (memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, mask / 8) != 0) + return false; + if (mask % 8 == 0) + return true; + bitmask = 255 << (mask % 8); + return (a->ip6.sin6_addr.s6_addr[mask / 8] & bitmask) == (b->ip6.sin6_addr.s6_addr[mask / 8] & bitmask); +} +#endif + static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) { UINT32 bitmask = INADDR_NONE; @@ -416,7 +430,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) && (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port)); #ifdef HAVE_IPV6 else if (b->any.sa_family == AF_INET6) - return !memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr)) + return SOCK_cmpipv6(a, b, mask) && (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port)); #endif else From fe87760c8c89f14186cb1c6395fe8fe0948dba33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 14 Dec 2023 17:15:07 +0100 Subject: [PATCH 63/85] Fix buffer overflow in SV_SendPlayerInfo --- src/netcode/server_connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index 258d4cce4..faff7e8dd 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -164,7 +164,7 @@ static void SV_SendPlayerInfo(INT32 node) for (UINT8 i = 0; i < MAXPLAYERS; i++) { - if (!netnodes[playernode[i]].ingame) + if (playernode[i] == UINT8_MAX || !netnodes[playernode[i]].ingame) { netbuffer->u.playerinfo[i].num = 255; // This slot is empty. continue; From bc96645f0b7583ced290a89c136a3651a49be406 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 14 Dec 2023 20:15:50 -0500 Subject: [PATCH 64/85] GitLabCI: use new builder image, srb2ci --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4e284ce65..49dd9bdf5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,7 +3,7 @@ variables: GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH default: - image: debian:stable-slim + image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:stable cache: - key: ccache-$CI_PROJECT_PATH_SLUG-$CI_JOB_NAME_SLUG From 1756fabef0de34f80bd9b5eba545f467af5c1b97 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 22 Dec 2023 11:24:56 +0100 Subject: [PATCH 65/85] Convert UDMF colormap light/fade alpha to new 0-255 range --- src/p_setup.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 6974eab53..442db9430 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2976,22 +2976,26 @@ static void P_LoadTextmap(void) P_InitializeSector(sc); if (textmap_colormap.used) { - INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, textmap_colormap.lightalpha); - INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, textmap_colormap.fadealpha); + // Convert alpha values from old 0-25 (A-Z) range to 0-255 range + UINT8 lightalpha = (textmap_colormap.lightalpha * 102) / 10; + UINT8 fadealpha = (textmap_colormap.fadealpha * 102) / 10; + + INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, lightalpha); + INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, fadealpha); sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags); } if (textmap_planefloor.defined == (PD_A|PD_B|PD_C|PD_D)) - { + { sc->f_slope = MakeViaEquationConstants(textmap_planefloor.a, textmap_planefloor.b, textmap_planefloor.c, textmap_planefloor.d); sc->hasslope = true; - } + } if (textmap_planeceiling.defined == (PD_A|PD_B|PD_C|PD_D)) - { + { sc->c_slope = MakeViaEquationConstants(textmap_planeceiling.a, textmap_planeceiling.b, textmap_planeceiling.c, textmap_planeceiling.d); sc->hasslope = true; - } + } TextmapFixFlatOffsets(sc); } From 7893d08407ba5b11f5dbad213c84180ced6179c0 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 22 Dec 2023 14:23:24 +0100 Subject: [PATCH 66/85] Fix realmapnamep not being set with map * and + --- src/g_game.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index f819cbd9a..578dc7c6c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5387,17 +5387,19 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) if (mapnamelen == 1) { if (mapname[0] == '*') // current map - return gamemap; + { + usemapcode = true; + newmapnum = gamemap; + } else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map { + usemapcode = true; newmapnum = mapheaderinfo[gamemap-1]->nextlevel; if (newmapnum < 1 || newmapnum > NUMMAPS) { CONS_Alert(CONS_ERROR, M_GetText("NextLevel (%d) is not a valid map.\n"), newmapnum); return 0; } - else - return newmapnum; } } else if (mapnamelen == 2)/* maybe two digit code */ From d79d22de63c5b84e3e0f4d737af81f74321dd80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 23 Dec 2023 11:05:14 +0100 Subject: [PATCH 67/85] (Hopefully) Fix chatbug --- src/netcode/d_net.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index cfb1963b9..5a2e229d3 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -313,9 +313,9 @@ static void RemoveAck(INT32 i) } // We have got a packet, proceed the ack request and ack return -static boolean Processackpak(void) +static int Processackpak(void) { - boolean goodpacket = true; + int goodpacket = 0; node_t *node = &nodes[doomcom->remotenode]; // Received an ack return, so remove the ack in the list @@ -340,7 +340,7 @@ static boolean Processackpak(void) { DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); duppacket++; - goodpacket = false; // Discard packet (duplicate) + goodpacket = 1; // Discard packet (duplicate) } else { @@ -350,10 +350,10 @@ static boolean Processackpak(void) { DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); duppacket++; - goodpacket = false; // Discard packet (duplicate) + goodpacket = 1; // Discard packet (duplicate) break; } - if (goodpacket) + if (goodpacket == 0) { // Is a good packet so increment the acknowledge number, // Then search for a "hole" in the queue @@ -414,12 +414,13 @@ static boolean Processackpak(void) else // Buffer full discard packet, sender will resend it { // We can admit the packet but we will not detect the duplication after :( DEBFILE("no more freeackret\n"); - goodpacket = false; + goodpacket = 2; } } } } } + // return values: 0 = ok, 1 = duplicate, 2 = out of order return goodpacket; } @@ -1069,6 +1070,7 @@ boolean HGetPacket(void) while(true) { //nodejustjoined = I_NetGet(); + int goodpacket; I_NetGet(); if (doomcom->remotenode == -1) // No packet received @@ -1114,8 +1116,15 @@ boolean HGetPacket(void) }*/ // Proceed the ack and ackreturn field - if (!Processackpak()) + goodpacket = Processackpak(); + if (goodpacket != 0) + { + // resend the ACK in case the previous ACK didn't reach the client. + // prevents the client's netbuffer from locking up. + if (goodpacket == 1) + Net_SendAcks(doomcom->remotenode); continue; // discarded (duplicated) + } // A packet with just ackreturn if (netbuffer->packettype == PT_NOTHING) From ddba6e80f7af16d712670c87efdcc3a30d319e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 23 Dec 2023 13:45:16 +0100 Subject: [PATCH 68/85] Handle player state is P_MobjSetState --- src/b_bot.c | 4 +- src/f_finale.c | 2 +- src/lua_mobjlib.c | 5 +- src/m_cheat.c | 6 +- src/p_enemy.c | 6 +- src/p_inter.c | 26 ++--- src/p_local.h | 1 - src/p_map.c | 28 +++--- src/p_mobj.c | 20 ++-- src/p_spec.c | 14 +-- src/p_telept.c | 4 +- src/p_user.c | 242 +++++++++++++++++++++++----------------------- src/r_skins.c | 2 +- 13 files changed, 177 insertions(+), 183 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index 033288a86..d5d5ab925 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -584,11 +584,11 @@ void B_RespawnBot(INT32 playernum) P_SetOrigin(tails, x, y, z); if (player->charability == CA_FLY) { - P_SetPlayerMobjState(tails, S_PLAY_FLY); + P_SetMobjState(tails, S_PLAY_FLY); tails->player->powers[pw_tailsfly] = (UINT16)-1; } else - P_SetPlayerMobjState(tails, S_PLAY_FALL); + P_SetMobjState(tails, S_PLAY_FALL); P_SetScale(tails, sonic->scale); tails->destscale = sonic->destscale; } diff --git a/src/f_finale.c b/src/f_finale.c index 68e9c3216..5dc18115c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -4524,7 +4524,7 @@ void F_TextPromptDrawer(void) if (players[j].mo->state == states+S_PLAY_STND && players[j].mo->tics != -1)\ players[j].mo->tics++;\ else if (players[j].mo->state == states+S_PLAY_WAIT)\ - P_SetPlayerMobjState(players[j].mo, S_PLAY_STND);\ + P_SetMobjState(players[j].mo, S_PLAY_STND);\ }\ } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 19f30b70e..d38e85a21 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -641,10 +641,7 @@ static int mobj_set(lua_State *L) mo->tics = luaL_checkinteger(L, 3); break; case mobj_state: // set state by enum - if (mo->player) - P_SetPlayerMobjState(mo, luaL_checkinteger(L, 3)); - else - P_SetMobjState(mo, luaL_checkinteger(L, 3)); + P_SetMobjState(mo, luaL_checkinteger(L, 3)); break; case mobj_flags: // special handling for MF_NOBLOCKMAP and MF_NOSECTOR { diff --git a/src/m_cheat.c b/src/m_cheat.c index 2bcf43ad1..e61db2c2e 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1019,7 +1019,7 @@ static void OP_CycleThings(INT32 amt) if (players[0].mo->eflags & MFE_VERTICALFLIP) // correct z when flipped players[0].mo->z += players[0].mo->height - FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale); players[0].mo->height = FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale); - P_SetPlayerMobjState(players[0].mo, S_OBJPLACE_DUMMY); + P_SetMobjState(players[0].mo, S_OBJPLACE_DUMMY); op_currentdoomednum = mobjinfo[op_currentthing].doomednum; } @@ -1528,7 +1528,7 @@ void Command_ObjectPlace_f(void) else OP_CycleThings(0); // sets all necessary height values without cycling op_currentthing - P_SetPlayerMobjState(players[0].mo, S_OBJPLACE_DUMMY); + P_SetMobjState(players[0].mo, S_OBJPLACE_DUMMY); } // Or are we leaving it instead? else @@ -1542,7 +1542,7 @@ void Command_ObjectPlace_f(void) // If still in dummy state, get out of it. if (players[0].mo->state == &states[S_OBJPLACE_DUMMY]) - P_SetPlayerMobjState(players[0].mo, op_oldstate); + P_SetMobjState(players[0].mo, op_oldstate); // Reset everything back to how it was before we entered objectplace. P_UnsetThingPosition(players[0].mo); diff --git a/src/p_enemy.c b/src/p_enemy.c index 93c828fbe..e27e7060e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -9780,7 +9780,7 @@ void A_SetObjectState(mobj_t *actor) if (!target->player) P_SetMobjState(target, locvar1); else - P_SetPlayerMobjState(target, locvar1); + P_SetMobjState(target, locvar1); } } @@ -13609,7 +13609,7 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) player->powers[pw_carry] = CR_DUSTDEVIL; player->powers[pw_nocontrol] = 2; P_SetTarget(&thing->tracer, dustdevil); - P_SetPlayerMobjState(thing, S_PLAY_PAIN); + P_SetMobjState(thing, S_PLAY_PAIN); if (dist > dragamount) { @@ -13632,7 +13632,7 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) player->powers[pw_nocontrol] = 0; P_SetTarget(&thing->tracer, NULL); S_StartSound(thing, sfx_wdjump); - P_SetPlayerMobjState(thing, S_PLAY_FALL); + P_SetMobjState(thing, S_PLAY_FALL); } thing->momz = thrust; diff --git a/src/p_inter.c b/src/p_inter.c index c3811cbe4..27e838617 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -526,7 +526,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) else if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) { player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); - P_SetPlayerMobjState(toucher, S_PLAY_FALL); + P_SetMobjState(toucher, S_PLAY_FALL); toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); toucher->momx = 7*toucher->momx>>3; toucher->momy = 7*toucher->momy>>3; @@ -1246,7 +1246,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_ResetPlayer(player); - P_SetPlayerMobjState(toucher, S_PLAY_FALL); + P_SetMobjState(toucher, S_PLAY_FALL); } } return; @@ -1553,7 +1553,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) { player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); - P_SetPlayerMobjState(toucher, S_PLAY_FALL); + P_SetMobjState(toucher, S_PLAY_FALL); toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); toucher->momx = 7*toucher->momx>>3; toucher->momy = 7*toucher->momy>>3; @@ -1604,7 +1604,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) { player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); - P_SetPlayerMobjState(toucher, S_PLAY_FALL); + P_SetMobjState(toucher, S_PLAY_FALL); toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); toucher->momx = 7*toucher->momx>>3; toucher->momy = 7*toucher->momy>>3; @@ -1640,7 +1640,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->momx = special->momy = 0; // Buenos Dias Mandy - P_SetPlayerMobjState(toucher, S_PLAY_STUN); + P_SetMobjState(toucher, S_PLAY_STUN); player->pflags &= ~PF_APPLYAUTOBRAKE; P_ResetPlayer(player); player->drawangle = special->angle + ANGLE_180; @@ -1719,7 +1719,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { player->powers[pw_carry] = CR_MACESPIN; S_StartSound(toucher, sfx_spin); - P_SetPlayerMobjState(toucher, S_PLAY_ROLL); + P_SetMobjState(toucher, S_PLAY_ROLL); } else player->powers[pw_carry] = CR_GENERIC; @@ -1780,7 +1780,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (player->bot && player->bot != BOT_MPAI && toucher->state-states != S_PLAY_GASP) S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots - P_SetPlayerMobjState(toucher, S_PLAY_GASP); + P_SetMobjState(toucher, S_PLAY_GASP); P_ResetPlayer(player); } @@ -1847,7 +1847,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; P_ResetPlayer(player); player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetPlayerMobjState(toucher, S_PLAY_FALL); + P_SetMobjState(toucher, S_PLAY_FALL); P_SetTarget(&toucher->tracer->target, NULL); P_KillMobj(toucher->tracer, toucher, special, 0); P_SetTarget(&toucher->tracer, NULL); @@ -3059,9 +3059,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget else if (target->player) { if (damagetype == DMG_DROWNED || damagetype == DMG_SPACEDROWN) - P_SetPlayerMobjState(target, target->info->xdeathstate); + P_SetMobjState(target, target->info->xdeathstate); else - P_SetPlayerMobjState(target, target->info->deathstate); + P_SetMobjState(target, target->info->deathstate); } else #ifdef DEBUG_NULL_DEATHSTATE @@ -3115,7 +3115,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source) } player->powers[pw_flashing] = flashingtics; - P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN); + P_SetMobjState(target, S_PLAY_NIGHTS_STUN); S_StartSound(target, sfx_nghurt); player->mo->spriteroll = 0; @@ -3336,7 +3336,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) if (!player->spectator) player->mo->flags2 &= ~MF2_DONTDRAW; - P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); + P_SetMobjState(player->mo, player->mo->info->deathstate); if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) { P_PlayerFlagBurst(player, false); @@ -3410,7 +3410,7 @@ static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, I P_InstaThrust(player->mo, ang, fallbackspeed); - P_SetPlayerMobjState(player->mo, S_PLAY_STUN); + P_SetMobjState(player->mo, S_PLAY_STUN); P_ResetPlayer(player); diff --git a/src/p_local.h b/src/p_local.h index ba033dc06..baa6bd753 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -296,7 +296,6 @@ void P_PrecipitationEffects(void); void P_RemoveMobj(mobj_t *th); boolean P_MobjWasRemoved(mobj_t *th); void P_RemoveSavegameMobj(mobj_t *th); -boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); void P_RunShields(void); void P_RunOverlays(void); diff --git a/src/p_map.c b/src/p_map.c index 6a152c563..b1a339ac0 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -264,7 +264,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) UINT8 secondjump = object->player->secondjump; UINT16 tailsfly = object->player->powers[pw_tailsfly]; if (object->player->pflags & PF_GLIDING) - P_SetPlayerMobjState(object, S_PLAY_FALL); + P_SetMobjState(object, S_PLAY_FALL); P_ResetPlayer(object->player); object->player->pflags |= pflags; object->player->secondjump = secondjump; @@ -403,7 +403,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } if (object->player->pflags & PF_GLIDING) - P_SetPlayerMobjState(object, S_PLAY_FALL); + P_SetMobjState(object, S_PLAY_FALL); if ((spring->info->painchance == 3)) { if (!(pflags = (object->player->pflags & PF_SPINNING)) && @@ -411,11 +411,11 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) || (spring->flags2 & MF2_AMBUSH))) { pflags = PF_SPINNING; - P_SetPlayerMobjState(object, S_PLAY_ROLL); + P_SetMobjState(object, S_PLAY_ROLL); S_StartSound(object, sfx_spin); } else - P_SetPlayerMobjState(object, S_PLAY_ROLL); + P_SetMobjState(object, S_PLAY_ROLL); } else { @@ -424,7 +424,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_THOKKED | PF_BOUNCING); // I still need these. if (wasSpindashing) // Ensure we're in the rolling state, and not spindash. - P_SetPlayerMobjState(object, S_PLAY_ROLL); + P_SetMobjState(object, S_PLAY_ROLL); if (object->player->charability == CA_GLIDEANDCLIMB && object->player->skidtime && (pflags & PF_JUMPED)) { @@ -439,7 +439,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities. { object->player->pflags |= P_GetJumpFlags(object->player); - P_SetPlayerMobjState(object, S_PLAY_JUMP); + P_SetMobjState(object, S_PLAY_JUMP); } else if ((spring->info->painchance == 2) || ((spring->info->painchance != 3) && (pflags & PF_BOUNCING))) // Adding momentum only. { @@ -456,16 +456,16 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->player->secondjump = secondjump; } else if (object->player->dashmode >= DASHMODE_THRESHOLD) - P_SetPlayerMobjState(object, S_PLAY_DASH); + P_SetMobjState(object, S_PLAY_DASH); else if (P_IsObjectOnGround(object)) - P_SetPlayerMobjState(object, (horizspeed >= FixedMul(object->player->runspeed, object->scale)) ? S_PLAY_RUN : S_PLAY_WALK); + P_SetMobjState(object, (horizspeed >= FixedMul(object->player->runspeed, object->scale)) ? S_PLAY_RUN : S_PLAY_WALK); else - P_SetPlayerMobjState(object, (object->momz > 0) ? S_PLAY_SPRING : S_PLAY_FALL); + P_SetMobjState(object, (object->momz > 0) ? S_PLAY_SPRING : S_PLAY_FALL); } else if (P_MobjFlip(object)*vertispeed > 0) - P_SetPlayerMobjState(object, S_PLAY_SPRING); + P_SetMobjState(object, S_PLAY_SPRING); else - P_SetPlayerMobjState(object, S_PLAY_FALL); + P_SetMobjState(object, S_PLAY_FALL); } else if (horizspeed && object->tracer @@ -547,7 +547,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (p && !p->powers[pw_tailsfly] && !p->powers[pw_carry]) // doesn't reset anim for Tails' flight { P_ResetPlayer(p); - P_SetPlayerMobjState(object, S_PLAY_FALL); + P_SetMobjState(object, S_PLAY_FALL); P_SetTarget(&object->tracer, spring); p->powers[pw_carry] = CR_FAN; } @@ -565,7 +565,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) { P_ResetPlayer(p); if (p->panim != PA_FALL) - P_SetPlayerMobjState(object, S_PLAY_FALL); + P_SetMobjState(object, S_PLAY_FALL); } break; default: @@ -1047,7 +1047,7 @@ static boolean PIT_CheckThing(mobj_t *thing) thing->flags2 &= ~MF2_DONTDRAW; // don't leave the rock invisible if it was flashing prior to boarding P_SetTarget(&thing->tracer, tmthing); P_ResetPlayer(tmthing->player); - P_SetPlayerMobjState(tmthing, S_PLAY_WALK); + P_SetMobjState(tmthing, S_PLAY_WALK); tmthing->player->powers[pw_carry] = CR_ROLLOUT; P_SetTarget(&tmthing->tracer, thing); if (!P_IsObjectOnGround(thing)) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1b2065920..621de3a42 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -177,7 +177,7 @@ static void P_CyclePlayerMobjState(mobj_t *mobj) // you can cycle through multiple states in a tic if (!mobj->tics && mobj->state) - if (!P_SetPlayerMobjState(mobj, mobj->state->nextstate)) + if (!P_SetMobjState(mobj, mobj->state->nextstate)) return; // freed itself } } @@ -188,7 +188,7 @@ static void P_CyclePlayerMobjState(mobj_t *mobj) // // Separate from P_SetMobjState because of the pw_flashing check and Super states // -boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) +static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) { state_t *st; player_t *player = mobj->player; @@ -514,10 +514,8 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) statenum_t i = state; // initial state statenum_t tempstate[NUMSTATES]; // for use with recursion -#ifdef PARANOIA if (mobj->player != NULL) - I_Error("P_SetMobjState used for player mobj. Use P_SetPlayerMobjState instead!\n(State called: %d)", state); -#endif + P_SetPlayerMobjState(mobj, state); if (recursion++) // if recursion detected, memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table @@ -1648,7 +1646,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) { // if in a walking frame, stop moving if (player->panim == PA_WALK) - P_SetPlayerMobjState(mo, S_PLAY_STND); + P_SetMobjState(mo, S_PLAY_STND); mo->momx = player->cmomx; mo->momy = player->cmomy; } @@ -2974,7 +2972,7 @@ void P_PlayerZMovement(mobj_t *mo) } // Get up if you fell. if (mo->player->panim == PA_PAIN) - P_SetPlayerMobjState(mo, S_PLAY_WALK); + P_SetMobjState(mo, S_PLAY_WALK); if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { // Handle landing on slope during Z movement @@ -3957,7 +3955,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) { mobj->player->secondjump = 0; mobj->player->powers[pw_tailsfly] = 0; - P_SetPlayerMobjState(mobj, S_PLAY_WALK); + P_SetMobjState(mobj, S_PLAY_WALK); } #endif mobj->eflags &= ~MFE_JUSTHITFLOOR; @@ -7549,7 +7547,7 @@ static void P_RosySceneryThink(mobj_t *mobj) if (stat == S_ROSY_HUG) { if (player->panim != PA_IDLE) - P_SetPlayerMobjState(mobj->target, S_PLAY_STND); + P_SetMobjState(mobj->target, S_PLAY_STND); player->pflags |= PF_STASIS; } @@ -11771,9 +11769,9 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) mobj->flags2 |= MF2_OBJECTFLIP; } if (mthing->args[0]) - P_SetPlayerMobjState(mobj, S_PLAY_FALL); + P_SetMobjState(mobj, S_PLAY_FALL); else if (metalrecording) - P_SetPlayerMobjState(mobj, S_PLAY_WAIT); + P_SetMobjState(mobj, S_PLAY_WAIT); } else z = floor; diff --git a/src/p_spec.c b/src/p_spec.c index 4263a4fc7..131a58d20 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2735,7 +2735,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) mo->player->rmomx = mo->player->rmomy = 1; mo->player->cmomx = mo->player->cmomy = 0; P_ResetPlayer(mo->player); - P_SetPlayerMobjState(mo, S_PLAY_STND); + P_SetMobjState(mo, S_PLAY_STND); // Reset bot too. if (bot) { @@ -2746,7 +2746,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) bot->player->rmomx = bot->player->rmomy = 1; bot->player->cmomx = bot->player->cmomy = 0; P_ResetPlayer(bot->player); - P_SetPlayerMobjState(bot, S_PLAY_STND); + P_SetMobjState(bot, S_PLAY_STND); } } break; @@ -4566,7 +4566,7 @@ static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *rove if (!(player->pflags & PF_SPINNING)) player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); } player->powers[pw_flashing] = TICRATE/3; @@ -4744,7 +4744,7 @@ static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end) if (player->mo->state-states != S_PLAY_ROLL) { - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); } } @@ -4958,7 +4958,7 @@ static void P_ProcessRopeHang(player_t *player, mtag_t sectag) player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; P_SetThingPosition(player->mo); - P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); + P_SetMobjState(player->mo, S_PLAY_RIDE); } static boolean P_SectorHasSpecial(sector_t *sec) @@ -5017,7 +5017,7 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t if (!player->powers[pw_carry]) { P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); P_SetTarget(&player->mo->tracer, player->mo); player->powers[pw_carry] = CR_FAN; } @@ -5032,7 +5032,7 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t if (!(player->pflags & PF_SPINNING)) { player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartAttackSound(player->mo, sfx_spin); if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale) diff --git a/src/p_telept.c b/src/p_telept.c index 66b05ff01..32669edaf 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -96,7 +96,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, P_ClearStarPost(starpostnum); P_ResetPlayer(thing->player); - P_SetPlayerMobjState(thing, S_PLAY_STND); + P_SetMobjState(thing, S_PLAY_STND); P_FlashPal(thing->player, PAL_MIXUP, 10); } @@ -153,7 +153,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle thing->player->rmomx = thing->player->rmomy = 0; thing->player->speed = 0; P_ResetPlayer(thing->player); - P_SetPlayerMobjState(thing, S_PLAY_STND); + P_SetMobjState(thing, S_PLAY_STND); thing->reactiontime = TICRATE/2; // don't move for about half a second thing->player->drawangle = angle; diff --git a/src/p_user.c b/src/p_user.c index a856d2592..f54eb4e6b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -694,7 +694,7 @@ static void P_DeNightserizePlayer(player_t *player) else if (player == &players[secondarydisplayplayer]) localaiming2 = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); // If in a special stage, add some preliminary exit time. if (G_IsSpecialStage(gamemap)) @@ -948,7 +948,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) P_RunNightserizeExecutors(player->mo); player->powers[pw_carry] = CR_NIGHTSMODE; - P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS1); + P_SetMobjState(player->mo, S_PLAY_NIGHTS_TRANS1); } pflags_t P_GetJumpFlags(player_t *player) @@ -994,7 +994,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) fixed_t fallbackspeed; P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, player->mo->info->painstate); + P_SetMobjState(player->mo, player->mo->info->painstate); if (player->mo->eflags & MFE_VERTICALFLIP) player->mo->z--; @@ -1345,7 +1345,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0; // Transformation animation - P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); + P_SetMobjState(player->mo, S_PLAY_SUPER_TRANS1); if (giverings && player->rings < 50) player->rings = 50; @@ -1398,7 +1398,7 @@ static void P_DoSuperDetransformation(player_t *player) player->powers[pw_flashing] = flashingtics-1; if (player->mo->sprite2 & FF_SPR2SUPER) - P_SetPlayerMobjState(player->mo, player->mo->state-states); + P_SetMobjState(player->mo, player->mo->state-states); // Inform the netgame that the champion has fallen in the heat of battle. if (!G_CoopGametype()) @@ -2265,12 +2265,12 @@ void P_DoPlayerExit(player_t *player) { player->climbing = 0; player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } else if (player->pflags & PF_STARTDASH) { player->pflags &= ~PF_STARTDASH; - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } player->powers[pw_underwater] = 0; player->powers[pw_spacetime] = 0; @@ -2359,7 +2359,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (!(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL && player->panim != PA_ETC && player->panim != PA_ABILITY && player->panim != PA_ABILITY2) { - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); } } @@ -2368,7 +2368,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (dorollstuff) { player->skidtime = TICRATE; - P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); + P_SetMobjState(player->mo, S_PLAY_GLIDE); P_SpawnSkidDust(player, player->mo->radius, true); // make sure the player knows they landed player->mo->tics = -1; } @@ -2381,7 +2381,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (player->mo->state-states != S_PLAY_GLIDE_LANDING) { P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING); + P_SetMobjState(player->mo, S_PLAY_GLIDE_LANDING); player->pflags |= PF_STASIS; if (player->speed > FixedMul(player->runspeed, player->mo->scale)) player->skidtime += player->mo->tics; @@ -2402,7 +2402,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (player->mo->state-states != S_PLAY_MELEE_LANDING) { mobjtype_t type = player->revitem; - P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); + P_SetMobjState(player->mo, S_PLAY_MELEE_LANDING); player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_s3k8b); player->pflags |= PF_FULLSTASIS; @@ -2465,28 +2465,28 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (player->cmomx || player->cmomy) { if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH) - P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + P_SetMobjState(player->mo, S_PLAY_DASH); else if (player->speed >= runspd && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + P_SetMobjState(player->mo, S_PLAY_RUN); else if ((player->rmomx || player->rmomy) && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } else { if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH) - P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + P_SetMobjState(player->mo, S_PLAY_DASH); else if (player->speed >= runspd && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + P_SetMobjState(player->mo, S_PLAY_RUN); else if ((player->mo->momx || player->mo->momy) && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } } @@ -2516,7 +2516,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ? 6*FRACUNIT/5 : 5*FRACUNIT/2, false); - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); player->mo->momx = player->mo->momy = 0; clipmomz = false; } @@ -3648,9 +3648,9 @@ static void P_DoClimbing(player_t *player) if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz) && player->mo->state-states != S_PLAY_CLIMB) - P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB); + P_SetMobjState(player->mo, S_PLAY_CLIMB); else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING) - P_SetPlayerMobjState(player->mo, S_PLAY_CLING); + P_SetMobjState(player->mo, S_PLAY_CLING); if (!floorclimb) { @@ -3665,14 +3665,14 @@ static void P_DoClimbing(player_t *player) player->climbing = 0; player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } if (skyclimber) { player->climbing = 0; player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } } @@ -3683,15 +3683,15 @@ static void P_DoClimbing(player_t *player) if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz) && player->mo->state-states != S_PLAY_CLIMB) - P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB); + P_SetMobjState(player->mo, S_PLAY_CLIMB); else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING) - P_SetPlayerMobjState(player->mo, S_PLAY_CLING); + P_SetMobjState(player->mo, S_PLAY_CLING); if (cmd->buttons & BT_SPIN && !(player->pflags & PF_JUMPSTASIS)) { player->climbing = 0; player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); P_SetObjectMomZ(player->mo, 4*FRACUNIT, false); P_Thrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale)); } @@ -3707,12 +3707,12 @@ static void P_DoClimbing(player_t *player) } if (player->climbing == 0) - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); if (player->climbing && P_IsObjectOnGround(player->mo)) { P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } } @@ -4074,10 +4074,10 @@ teeterdone: if (teeter) { if (player->panim == PA_IDLE) - P_SetPlayerMobjState(player->mo, S_PLAY_EDGE); + P_SetMobjState(player->mo, S_PLAY_EDGE); } else if (player->panim == PA_EDGE) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } // @@ -4602,7 +4602,7 @@ void P_DoJump(player_t *player, boolean soundandstate) if (!player->spectator) S_StartSound(player->mo, sfx_jump); // Play jump sound! - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } } @@ -4672,7 +4672,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momy = player->cmomy; player->pflags |= (PF_SPINDOWN|PF_STARTDASH|PF_SPINNING); player->dashspeed = player->mindash; - P_SetPlayerMobjState(player->mo, S_PLAY_SPINDASH); + P_SetMobjState(player->mo, S_PLAY_SPINDASH); if (!player->spectator) S_StartSound(player->mo, sfx_spndsh); // Make the rev sound! } @@ -4682,7 +4682,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (player->speed > 5*player->mo->scale) { player->pflags &= ~PF_STARTDASH; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); break; } @@ -4715,7 +4715,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) || !canstand) && !(player->pflags & (PF_SPINDOWN|PF_SPINNING))) { player->pflags |= (PF_SPINDOWN|PF_SPINNING); - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); if (!player->spectator) S_StartSound(player->mo, sfx_spin); } @@ -4731,12 +4731,12 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { if (player->dashspeed) { - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); P_InstaThrust(player->mo, player->mo->angle, (player->speed = FixedMul(player->dashspeed, player->mo->scale))); // catapult forward ho!! } else { - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); player->pflags &= ~PF_SPINNING; } @@ -4768,7 +4768,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { mobj_t *bullet; - P_SetPlayerMobjState(player->mo, S_PLAY_FIRE); + P_SetMobjState(player->mo, S_PLAY_FIRE); #define zpos(posmo) (posmo->z + (posmo->height - mobjinfo[player->revitem].height)/2) if (lockon) @@ -4812,7 +4812,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) P_DoJump(player, false); player->pflags &= ~PF_STARTJUMP; player->mo->momz = FixedMul(player->mo->momz, 3*FRACUNIT/2); // NOT 1.5 times the jump height, but 2.25 times. - P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); + P_SetMobjState(player->mo, S_PLAY_TWINSPIN); S_StartSound(player->mo, sfx_s3k8b); } else @@ -4838,7 +4838,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) } player->mo->momx += player->cmomx; player->mo->momy += player->cmomy; - P_SetPlayerMobjState(player->mo, S_PLAY_MELEE); + P_SetMobjState(player->mo, S_PLAY_MELEE); player->powers[pw_strong] = STR_MELEE; S_StartSound(player->mo, sfx_s3k42); } @@ -4862,7 +4862,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { player->skidtime = 0; player->pflags &= ~PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); player->mo->momx = player->cmomx; player->mo->momy = player->cmomy; } @@ -4911,13 +4911,13 @@ void P_DoJumpShield(player_t *player) #undef limitangle #undef numangles player->pflags &= ~PF_NOJUMPDAMAGE; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_s3k45); } else { player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); S_StartSound(player->mo, sfx_wdjump); } } @@ -4934,9 +4934,9 @@ void P_DoBubbleBounce(player_t *player) P_MobjCheckWater(player->mo); P_DoJump(player, false); if (player->charflags & SF_NOJUMPSPIN) - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); else - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); player->pflags |= PF_THOKKED; player->pflags &= ~PF_STARTJUMP; player->secondjump = UINT8_MAX; @@ -4973,7 +4973,7 @@ void P_DoAbilityBounce(player_t *player, boolean changemomz) } S_StartSound(player->mo, sfx_boingf); - P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE_LANDING); + P_SetMobjState(player->mo, S_PLAY_BOUNCE_LANDING); player->pflags |= PF_BOUNCING|PF_THOKKED; } @@ -5086,7 +5086,7 @@ static void P_DoTwinSpin(player_t *player) player->pflags |= P_GetJumpFlags(player) | PF_THOKKED; S_StartSound(player->mo, sfx_s3k42); player->mo->frame = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); + P_SetMobjState(player->mo, S_PLAY_TWINSPIN); player->powers[pw_strong] = STR_TWINSPIN; } @@ -5160,7 +5160,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock { player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockonshield->x, lockonshield->y); player->pflags &= ~PF_NOJUMPDAMAGE; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_s3k40); player->homing = 3*TICRATE; } @@ -5184,7 +5184,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock player->mo->momx -= (player->mo->momx/3); player->mo->momy -= (player->mo->momy/3); player->pflags &= ~PF_NOJUMPDAMAGE; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_s3k44); } player->secondjump = 0; @@ -5197,7 +5197,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock P_Thrust(player->mo, player->mo->angle, FixedMul(30*FRACUNIT - FixedSqrt(FixedDiv(player->speed, player->mo->scale)), player->mo->scale)); player->drawangle = player->mo->angle; player->pflags &= ~(PF_NOJUMPDAMAGE|PF_SPINNING); - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_s3k43); default: break; @@ -5259,9 +5259,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (player->panim != PA_RUN && player->panim != PA_WALK) { if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); + P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN); else - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT); + P_SetMobjState(player->mo, S_PLAY_FLOAT); } player->mo->momz = 0; @@ -5392,13 +5392,13 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockonthok)); if (lockonthok) { - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockonthok->x, lockonthok->y); player->homing = 3*TICRATE; } else { - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); player->pflags &= ~PF_JUMPED; player->mo->height = P_GetPlayerHeight(player); } @@ -5435,7 +5435,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) ; // Can't do anything if you're a fish out of water! else if (!(player->pflags & PF_THOKKED) && !(player->powers[pw_tailsfly])) { - P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation + P_SetMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer @@ -5468,7 +5468,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags |= PF_GLIDING|PF_THOKKED; player->glidetime = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); + P_SetMobjState(player->mo, S_PLAY_GLIDE); if (playerspeed < glidespeed) P_Thrust(player->mo, player->mo->angle, glidespeed - playerspeed); player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH); @@ -5489,11 +5489,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD) - P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + P_SetMobjState(player->mo, S_PLAY_DASH); else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); + P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN); else - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT); + P_SetMobjState(player->mo, S_PLAY_FLOAT); player->pflags |= PF_THOKKED; player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING); player->secondjump = 1; @@ -5529,7 +5529,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) case CA_BOUNCE: if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { - P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE); + P_SetMobjState(player->mo, S_PLAY_BOUNCE); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING); player->pflags |= PF_THOKKED|PF_BOUNCING; player->powers[pw_strong] = STR_BOUNCE; @@ -5619,7 +5619,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (!(player->mo->tracer->flags & MF_BOSS)) player->pflags &= ~PF_THOKKED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); + P_SetMobjState(player->mo, S_PLAY_SPRING); player->pflags |= PF_NOJUMPDAMAGE; } } @@ -5667,7 +5667,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) else player->secondjump = 2; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); } // If letting go of the jump button while still on ascent, cut the jump height. @@ -5787,7 +5787,7 @@ static void P_2dMovement(player_t *player) else if (player->exiting) { player->pflags &= ~PF_GLIDING; - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); player->skidtime = 0; } } @@ -5796,7 +5796,7 @@ static void P_2dMovement(player_t *player) if (player->pflags & PF_SPINNING && !player->exiting) { player->pflags &= ~PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } } @@ -5960,7 +5960,7 @@ static void P_3dMovement(player_t *player) else if (player->exiting) { player->pflags &= ~PF_GLIDING; - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); player->skidtime = 0; } } @@ -5969,7 +5969,7 @@ static void P_3dMovement(player_t *player) if (player->pflags & PF_SPINNING && !player->exiting) { player->pflags &= ~PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } } @@ -6011,7 +6011,7 @@ static void P_3dMovement(player_t *player) if (player->pflags & PF_SLIDING) cmd->forwardmove = 0; else if (onground && player->mo->state == states+S_PLAY_PAIN) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); player->aiming = cmd->aiming<mo->momx || player->mo->momy || player->mo->momz) { if (player->mo->state != &states[S_PLAY_NIGHTS_PULL]) - P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_PULL); + P_SetMobjState(player->mo, S_PLAY_NIGHTS_PULL); } else if (player->mo->state != &states[S_PLAY_NIGHTS_ATTACK]) { S_StartSound(player->mo, sfx_spin); - P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_ATTACK); + P_SetMobjState(player->mo, S_PLAY_NIGHTS_ATTACK); } } else @@ -6829,7 +6829,7 @@ static void P_DoNiGHTSCapsule(player_t *player) if (!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING)) player->pflags |= PF_JUMPED; if (player->panim != PA_ROLL) - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); } if (!(player->charflags & SF_NONIGHTSROTATION)) @@ -7308,14 +7308,14 @@ static void P_NiGHTSMovement(player_t *player) if (!(player->charflags & SF_NONIGHTSROTATION) && player->mo->momz) { if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL]) - P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL); + P_SetMobjState(player->mo, S_PLAY_NIGHTS_DRILL); player->mo->spriteroll = ANGLE_90; } else #endif { if (player->mo->state != &states[S_PLAY_NIGHTS_FLOAT]) - P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_FLOAT); + P_SetMobjState(player->mo, S_PLAY_NIGHTS_FLOAT); player->drawangle += ANGLE_22h; } @@ -7639,7 +7639,7 @@ static void P_NiGHTSMovement(player_t *player) } if (player->mo->state != &states[flystate]) - P_SetPlayerMobjState(player->mo, flystate); + P_SetMobjState(player->mo, flystate); if (player->charflags & SF_NONIGHTSROTATION) player->mo->spriteroll = 0; @@ -7905,13 +7905,13 @@ static void P_SkidStuff(player_t *player) player->skidtime = 0; player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); player->pflags |= PF_THOKKED; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); } // Get up and brush yourself off, idiot. else if (player->glidetime > 15 || !(player->cmd.buttons & BT_JUMP)) { P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING); + P_SetMobjState(player->mo, S_PLAY_GLIDE_LANDING); player->pflags |= PF_STASIS; if (player->speed > FixedMul(player->runspeed, player->mo->scale)) player->skidtime += player->mo->tics; @@ -7956,7 +7956,7 @@ static void P_SkidStuff(player_t *player) if (dang > ANGLE_157h) { if (player->mo->state-states != S_PLAY_SKID) - P_SetPlayerMobjState(player->mo, S_PLAY_SKID); + P_SetMobjState(player->mo, S_PLAY_SKID); player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_skid); } @@ -8188,63 +8188,63 @@ void P_MovePlayer(player_t *player) { // If the player is in dashmode, here's their peelout. if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim == PA_RUN && !player->skidtime && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) - P_SetPlayerMobjState (player->mo, S_PLAY_DASH); + P_SetMobjState (player->mo, S_PLAY_DASH); // If the player is moving fast enough, // break into a run! else if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) { if (!onground) - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); + P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN); else - P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + P_SetMobjState(player->mo, S_PLAY_RUN); } // Floating at slow speeds has its own special animation. else if ((((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) && player->panim == PA_IDLE && !onground) - P_SetPlayerMobjState (player->mo, S_PLAY_FLOAT); + P_SetMobjState (player->mo, S_PLAY_FLOAT); // Otherwise, just walk. else if ((player->rmomx || player->rmomy) && player->panim == PA_IDLE) - P_SetPlayerMobjState (player->mo, S_PLAY_WALK); + P_SetMobjState (player->mo, S_PLAY_WALK); } // If your peelout animation is playing, and you're // going too slow, switch back to the run. if (player->charflags & SF_DASHMODE && player->panim == PA_DASH && player->dashmode < DASHMODE_THRESHOLD) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + P_SetMobjState(player->mo, S_PLAY_RUN); // If your running animation is playing, and you're // going too slow, switch back to the walking frames. if (player->panim == PA_RUN && player->speed < runspd) { if (!onground && (((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) - P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT); + P_SetMobjState(player->mo, S_PLAY_FLOAT); else - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); } // Correct floating when ending up on the ground. if (onground) { if (player->mo->state-states == S_PLAY_FLOAT) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else if (player->mo->state-states == S_PLAY_FLOAT_RUN) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + P_SetMobjState(player->mo, S_PLAY_RUN); } // If Springing (or nojumpspinning), but travelling DOWNWARD, change back! if ((player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0) || ((((player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED) && player->panim == PA_JUMP)) && (P_MobjFlip(player->mo)*player->mo->momz < 0))) - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); // If doing an air animation but on the ground, change back! else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE || player->panim == PA_JUMP) && !player->mo->momz) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); // If you are stopped and are still walking, stand still! if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); ////////////////// //GAMEPLAY STUFF// @@ -8256,18 +8256,18 @@ void P_MovePlayer(player_t *player) { player->pflags &= ~(PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY); player->secondjump = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); } if ((!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? && (player->pflags & PF_GLIDING || player->climbing)) { if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else { player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } player->pflags &= ~PF_GLIDING; player->glidetime = 0; @@ -8278,11 +8278,11 @@ void P_MovePlayer(player_t *player) && (player->pflags & PF_BOUNCING)) { if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else { player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } player->pflags &= ~PF_BOUNCING; } @@ -8399,18 +8399,18 @@ void P_MovePlayer(player_t *player) { P_ResetPlayer(player); // down, stop gliding. if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else if (player->charflags & SF_MULTIABILITY) { player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } else { player->pflags |= PF_THOKKED; player->mo->momx >>= 1; player->mo->momy >>= 1; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); } } } @@ -8427,23 +8427,23 @@ void P_MovePlayer(player_t *player) P_ResetPlayer(player); // down, stop bouncing. player->pflags |= PF_THOKKED; if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else if (player->charflags & SF_MULTIABILITY) { player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } else { player->mo->momx >>= 1; player->mo->momy >>= 1; player->mo->momz >>= 1; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); } } } else if (player->mo->state-states == S_PLAY_BOUNCE) - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); // If you're running fast enough, you can create splashes as you run in shallow water. if (!player->climbing @@ -8487,11 +8487,11 @@ void P_MovePlayer(player_t *player) || player->mo->state-states == S_PLAY_FLY_TIRED) { if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); else { player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } } player->powers[pw_tailsfly] = 0; @@ -8525,7 +8525,7 @@ void P_MovePlayer(player_t *player) if (P_MobjFlip(player->mo)*player->mo->momz < FixedMul(5*actionspd, player->mo->scale)) P_SetObjectMomZ(player->mo, actionspd/2, true); - P_SetPlayerMobjState(player->mo, player->mo->state->nextstate); + P_SetMobjState(player->mo, player->mo->state->nextstate); player->fly1--; } @@ -8553,7 +8553,7 @@ void P_MovePlayer(player_t *player) { // Tails-gets-tired Stuff if (player->panim == PA_ABILITY && player->mo->state-states != S_PLAY_FLY_TIRED) - P_SetPlayerMobjState(player->mo, S_PLAY_FLY_TIRED); + P_SetMobjState(player->mo, S_PLAY_FLY_TIRED); if (player->charability == CA_FLY && (leveltime % 10 == 0) && player->mo->state-states == S_PLAY_FLY_TIRED @@ -8670,7 +8670,7 @@ void P_MovePlayer(player_t *player) // Make sure you're not teetering when you shouldn't be. if (player->panim == PA_EDGE && (player->mo->momx || player->mo->momy || player->mo->momz)) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); // Check for teeter! if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) @@ -8736,7 +8736,7 @@ void P_MovePlayer(player_t *player) if (!atspinheight) { player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); } else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) { @@ -8917,7 +8917,7 @@ static void P_DoRopeHang(player_t *player) if (player->cmd.buttons & BT_SPIN && !(player->pflags & PF_STASIS)) // Drop off of the rope { player->pflags |= (P_GetJumpFlags(player)|PF_SPINDOWN); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); P_SetTarget(&player->mo->tracer, NULL); player->powers[pw_carry] = CR_NONE; @@ -8926,7 +8926,7 @@ static void P_DoRopeHang(player_t *player) } if (player->mo->state-states != S_PLAY_RIDE) - P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); + P_SetMobjState(player->mo, S_PLAY_RIDE); // If not allowed to move, we're done here. if (!speed) @@ -8982,7 +8982,7 @@ static void P_DoRopeHang(player_t *player) if (player->mo->tracer->flags & MF_SLIDEME) { player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetMobjState(player->mo, S_PLAY_JUMP); } P_SetTarget(&player->mo->tracer, NULL); @@ -11180,7 +11180,7 @@ static void P_MinecartThink(player_t *player) if (player->mo->state-states != S_PLAY_STND) { - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); player->mo->tics = -1; } @@ -11958,7 +11958,7 @@ void P_PlayerThink(player_t *player) { P_DoZoomTube(player); if (!(player->panim == PA_ROLL)) - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); } player->rmomx = player->rmomy = 0; // no actual momentum from your controls P_ResetScore(player); @@ -12117,7 +12117,7 @@ void P_PlayerThink(player_t *player) { statenum_t stat = player->mo->state-states; if (stat == S_PLAY_WAIT) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); else if (stat == S_PLAY_STND && player->mo->tics != -1) player->mo->tics++; } @@ -12144,7 +12144,7 @@ void P_PlayerThink(player_t *player) else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl { if (player->mo->state-states != S_PLAY_SKID) - P_SetPlayerMobjState(player->mo, S_PLAY_SKID); + P_SetMobjState(player->mo, S_PLAY_SKID); player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; if (P_IsLocalPlayer(player)) // the sound happens way more frequently now, so give co-op players' ears a brake... @@ -12321,7 +12321,7 @@ void P_PlayerThink(player_t *player) if (!player->powers[pw_flashing]) { if (player->mo->state != &states[S_PLAY_STND]) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + P_SetMobjState(player->mo, S_PLAY_STND); else player->mo->tics = 2; } @@ -12682,7 +12682,7 @@ void P_PlayerAfterThink(player_t *player) S_StartSound(NULL, sfx_wepchg); if ((player->pflags & PF_SLIDING) && ((player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) != PF_JUMPED)) - P_SetPlayerMobjState(player->mo, player->mo->info->painstate); + P_SetMobjState(player->mo, player->mo->info->painstate); /* if (player->powers[pw_carry] == CR_NONE && player->mo->tracer && !player->homing) P_SetTarget(&player->mo->tracer, NULL); @@ -12743,7 +12743,7 @@ void P_PlayerAfterThink(player_t *player) if (player->powers[pw_carry] == CR_PLAYER) { if (player->mo->state-states != S_PLAY_RIDE) - P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); + P_SetMobjState(player->mo, S_PLAY_RIDE); if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) tails->player->powers[pw_tailsfly] = 0; } @@ -12768,7 +12768,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->momx = player->mo->momy = player->mo->momz = 0; P_SetThingPosition(player->mo); if (player->mo->state-states != S_PLAY_RIDE) - P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); + P_SetMobjState(player->mo, S_PLAY_RIDE); // Controllable missile if (item->type == MT_BLACKEGGMAN_MISSILE) @@ -12889,7 +12889,7 @@ void P_PlayerAfterThink(player_t *player) if (player->panim == PA_IDLE && (mo->momx || mo->momy)) { - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + P_SetMobjState(player->mo, S_PLAY_WALK); } if (player->panim == PA_WALK && mo->tics > walktics) @@ -12945,7 +12945,7 @@ void P_PlayerAfterThink(player_t *player) P_KillMobj(ptera, player->mo, player->mo, 0); P_SetObjectMomZ(player->mo, 12*FRACUNIT, false); player->pflags |= PF_APPLYAUTOBRAKE|PF_JUMPED|PF_THOKKED; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_SetMobjState(player->mo, S_PLAY_ROLL); break; } @@ -12966,7 +12966,7 @@ void P_PlayerAfterThink(player_t *player) ptera->cvmem >>= 1; if (player->mo->state-states != S_PLAY_FALL) - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + P_SetMobjState(player->mo, S_PLAY_FALL); break; dropoff: diff --git a/src/r_skins.c b/src/r_skins.c index 308cee8d6..fbc2a30e1 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -392,7 +392,7 @@ static void SetSkin(player_t *player, INT32 skinnum) P_SetScale(player->mo, player->mo->scale); player->mo->radius = radius; - P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames + P_SetMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames } } From ac34fdf1290b31e772c88dee3b866e6950511554 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 23 Dec 2023 13:14:47 +0000 Subject: [PATCH 69/85] Apply 1 suggestion(s) to 1 file(s) --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 621de3a42..2a627ce01 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -515,7 +515,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) statenum_t tempstate[NUMSTATES]; // for use with recursion if (mobj->player != NULL) - P_SetPlayerMobjState(mobj, state); + return P_SetPlayerMobjState(mobj, state); if (recursion++) // if recursion detected, memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table From 6a4b26a04c8e90acf19a0effba17333a3e0420fe Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sat, 23 Dec 2023 16:30:45 -0300 Subject: [PATCH 70/85] Fix #1158 --- src/r_draw.c | 19 ++-- src/r_draw.h | 7 +- src/r_draw8.c | 160 ++++++++++++++++----------------- src/r_draw8_npo2.c | 144 +++++++++++++++--------------- src/r_main.c | 13 --- src/r_plane.c | 214 ++++++++++++++++++++++++--------------------- src/r_plane.h | 5 -- src/r_splats.c | 4 +- 8 files changed, 271 insertions(+), 295 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index 671767b21..643f843d3 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -106,14 +106,13 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; INT32 ds_waterofs, ds_bgofs; UINT16 ds_flatwidth, ds_flatheight; -boolean ds_powersoftwo, ds_solidcolor; +boolean ds_powersoftwo, ds_solidcolor, ds_fog; UINT8 *ds_source; // points to the start of a flat UINT8 *ds_transmap; // one of the translucency tables // Vectors for Software's tilted slope drawers -floatv3_t *ds_su, *ds_sv, *ds_sz; -floatv3_t *ds_sup, *ds_svp, *ds_szp; +floatv3_t ds_su, ds_sv, ds_sz, ds_slopelight; float focallengthf, zeroheight; /** \brief Variable flat sizes @@ -906,13 +905,15 @@ static void R_CalcTiltedLighting(fixed_t start, fixed_t end) } } +#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan)) + // Lighting is simple. It's just linear interpolation from start to end -#define CALC_SLOPE_LIGHT { \ - float planelightfloat = PLANELIGHTFLOAT; \ - float lightstart, lightend; \ - lightend = (iz + ds_szp->x*width) * planelightfloat; \ - lightstart = iz * planelightfloat; \ - R_CalcTiltedLighting(FloatToFixed(lightstart), FloatToFixed(lightend)); \ +static void R_CalcSlopeLight(void) +{ + float iz = ds_slopelight.z + ds_slopelight.y * (centery - ds_y) + ds_slopelight.x * (ds_x1 - centerx); + float lightstart = iz * PLANELIGHTFLOAT; + float lightend = (iz + ds_slopelight.x * (ds_x2 - ds_x1)) * PLANELIGHTFLOAT; + R_CalcTiltedLighting(FloatToFixed(lightstart), FloatToFixed(lightend)); } // ========================================================================== diff --git a/src/r_draw.h b/src/r_draw.h index 0103ed827..0f08a48bf 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -61,7 +61,7 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; extern INT32 ds_waterofs, ds_bgofs; extern UINT16 ds_flatwidth, ds_flatheight; -extern boolean ds_powersoftwo, ds_solidcolor; +extern boolean ds_powersoftwo, ds_solidcolor, ds_fog; extern UINT8 *ds_source; extern UINT8 *ds_transmap; @@ -71,8 +71,7 @@ typedef struct { } floatv3_t; // Vectors for Software's tilted slope drawers -extern floatv3_t *ds_su, *ds_sv, *ds_sz; -extern floatv3_t *ds_sup, *ds_svp, *ds_szp; +extern floatv3_t ds_su, ds_sv, ds_sz, ds_slopelight; extern float focallengthf, zeroheight; // Variable flat sizes @@ -178,8 +177,6 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void); void R_DrawFogColumn_8(void); void R_DrawColumnShadowed_8(void); -#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan)) - void R_DrawSpan_8(void); void R_DrawTranslucentSpan_8(void); void R_DrawTiltedSpan_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index b80a47984..fe7d321df 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -676,12 +676,11 @@ void R_DrawTiltedSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -700,18 +699,18 @@ void R_DrawTiltedSpan_8(void) *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -753,9 +752,9 @@ void R_DrawTiltedSpan_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -799,12 +798,11 @@ void R_DrawTiltedTranslucentSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -822,18 +820,18 @@ void R_DrawTiltedTranslucentSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -875,9 +873,9 @@ void R_DrawTiltedTranslucentSpan_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -922,12 +920,11 @@ void R_DrawTiltedWaterSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; @@ -946,18 +943,18 @@ void R_DrawTiltedWaterSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -999,9 +996,9 @@ void R_DrawTiltedWaterSpan_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1044,12 +1041,11 @@ void R_DrawTiltedSplat_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -1071,18 +1067,18 @@ void R_DrawTiltedSplat_8(void) *dest = colormap[val]; dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -1128,9 +1124,9 @@ void R_DrawTiltedSplat_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1613,9 +1609,9 @@ void R_DrawTiltedFloorSprite_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = (UINT16 *)ds_source; @@ -1626,9 +1622,9 @@ void R_DrawTiltedFloorSprite_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -1673,9 +1669,9 @@ void R_DrawTiltedFloorSprite_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1722,9 +1718,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = (UINT16 *)ds_source; @@ -1735,9 +1731,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -1782,9 +1778,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -2013,9 +2009,7 @@ void R_DrawTiltedFogSpan_8(void) UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; - double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - - CALC_SLOPE_LIGHT + R_CalcSlopeLight(); do { @@ -2067,9 +2061,7 @@ void R_DrawTiltedSolidColorSpan_8(void) UINT8 source = ds_source[0]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; - double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - - CALC_SLOPE_LIGHT + R_CalcSlopeLight(); do { @@ -2088,9 +2080,7 @@ void R_DrawTiltedTransSolidColorSpan_8(void) UINT8 source = ds_source[0]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; - double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - - CALC_SLOPE_LIGHT + R_CalcSlopeLight(); do { @@ -2131,9 +2121,7 @@ void R_DrawTiltedWaterSolidColorSpan_8(void) UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; - double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - - CALC_SLOPE_LIGHT + R_CalcSlopeLight(); do { diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 91f3b06c4..78cde8a2c 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -114,12 +114,11 @@ void R_DrawTiltedSpan_NPO2_8(void) struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -154,18 +153,18 @@ void R_DrawTiltedSpan_NPO2_8(void) *dest = colormap[source[((y * ds_flatwidth) + x)]]; } dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -239,9 +238,9 @@ void R_DrawTiltedSpan_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -304,12 +303,11 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -343,18 +341,18 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); } dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -428,9 +426,9 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -492,12 +490,11 @@ void R_DrawTiltedSplat_NPO2_8(void) struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -536,18 +533,18 @@ void R_DrawTiltedSplat_NPO2_8(void) *dest = colormap[val]; dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -625,9 +622,9 @@ void R_DrawTiltedSplat_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -970,9 +967,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = (UINT16 *)ds_source; @@ -983,9 +980,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -1060,9 +1057,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1126,9 +1123,9 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = (UINT16 *)ds_source; @@ -1139,9 +1136,9 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -1216,9 +1213,9 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1411,12 +1408,11 @@ void R_DrawTiltedWaterSpan_NPO2_8(void) struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); - CALC_SLOPE_LIGHT - - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + R_CalcSlopeLight(); dest = ylookup[ds_y] + columnofs[ds_x1]; dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; @@ -1451,18 +1447,18 @@ void R_DrawTiltedWaterSpan_NPO2_8(void) *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); } dest++; - iz += ds_szp->x; - uz += ds_sup->x; - vz += ds_svp->x; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; } while (--width >= 0); #else startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; //x1 = 0; width++; @@ -1536,9 +1532,9 @@ void R_DrawTiltedWaterSpan_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; endz = 1.f/iz; endu = uz*endz; diff --git a/src/r_main.c b/src/r_main.c index 0cfccab8c..8c071ebad 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -957,16 +957,6 @@ void R_ExecuteSetViewSize(void) dy = FixedMul(abs(dy), fovtan); yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy); } - - if (ds_su) - Z_Free(ds_su); - if (ds_sv) - Z_Free(ds_sv); - if (ds_sz) - Z_Free(ds_sz); - - ds_su = ds_sv = ds_sz = NULL; - ds_sup = ds_svp = ds_szp = NULL; } memset(scalelight, 0xFF, sizeof(scalelight)); @@ -1012,9 +1002,6 @@ void R_Init(void) R_InitViewBorder(); R_SetViewSize(); // setsizeneeded is set true - //I_OutputMsg("\nR_InitPlanes"); - R_InitPlanes(); - // this is now done by SCR_Recalc() at the first mode set //I_OutputMsg("\nR_InitLightTables"); R_InitLightTables(); diff --git a/src/r_plane.c b/src/r_plane.c index 9c87ecbe4..08e147c89 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -84,16 +84,14 @@ fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t *yslope; static fixed_t xoffs, yoffs; -static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v; +static floatv3_t slope_origin, slope_u, slope_v; +static floatv3_t slope_lightu, slope_lightv; -// -// R_InitPlanes -// Only at game startup. -// -void R_InitPlanes(void) -{ - // FIXME: unused -} +static void CalcSlopePlaneVectors(visplane_t *pl, fixed_t xoff, fixed_t yoff); +static void CalcSlopeLightVectors(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t height, float ang, angle_t plangle); + +static void DoSlopeCrossProducts(void); +static void DoSlopeLightCrossProduct(void); // // Water ripple effect @@ -224,9 +222,9 @@ static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2) { ds_bgofs = R_CalculateRippleOffset(y); - ds_sup = &ds_su[y]; - ds_svp = &ds_sv[y]; - ds_szp = &ds_sz[y]; + R_CalculatePlaneRipple(currentplane->viewangle + currentplane->plangle); + + CalcSlopePlaneVectors(currentplane, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac)); ds_bgofs >>= FRACBITS; @@ -672,8 +670,6 @@ static INT64 R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) // Sets the texture origin vector of the sloped plane. static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) { - floatv3_t *p = &ds_slope_origin; - INT64 vx = (INT64)xpos + (INT64)xoff; INT64 vy = (INT64)ypos - (INT64)yoff; @@ -681,125 +677,157 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f float vyf = vy / (float)FRACUNIT; float ang = ANG2RAD(ANGLE_270 - angle); - // p is the texture origin in view space + // slope_origin is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in // errors if the flat is rotated. - p->x = vxf * cos(ang) - vyf * sin(ang); - p->z = vxf * sin(ang) + vyf * cos(ang); - p->y = (R_GetSlopeZAt(slope, -xoff, yoff) - zpos) / (float)FRACUNIT; + slope_origin.x = vxf * cos(ang) - vyf * sin(ang); + slope_origin.z = vxf * sin(ang) + vyf * cos(ang); + slope_origin.y = (R_GetSlopeZAt(slope, -xoff, yoff) - zpos) / (float)FRACUNIT; } // This function calculates all of the vectors necessary for drawing a sloped plane. void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) { - // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! // I copied ZDoom's code and adapted it to SRB2... -Red - floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; - fixed_t height, temp; + fixed_t height, z_at_xy; float ang; R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); height = P_GetSlopeZAt(slope, xpos, ypos); zeroheight = FixedToFloat(height - zpos); - // m is the v direction vector in view space ang = ANG2RAD(ANGLE_180 - (angle + plangle)); - m->x = cos(ang); - m->z = sin(ang); - // n is the u direction vector in view space - n->x = sin(ang); - n->z = -cos(ang); + CalcSlopeLightVectors(slope, xpos, ypos, height, ang, plangle); + + if (ds_solidcolor || ds_fog) + { + DoSlopeLightCrossProduct(); + return; + } + + // slope_v is the v direction vector in view space + slope_v.x = cos(ang); + slope_v.z = sin(ang); + + // slope_u is the u direction vector in view space + slope_u.x = sin(ang); + slope_u.z = -cos(ang); plangle >>= ANGLETOFINESHIFT; - temp = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle)); - m->y = FixedToFloat(temp - height); - temp = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle)); - n->y = FixedToFloat(temp - height); + z_at_xy = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle)); + slope_v.y = FixedToFloat(z_at_xy - height); + z_at_xy = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle)); + slope_u.y = FixedToFloat(z_at_xy - height); + + DoSlopeCrossProducts(); + DoSlopeLightCrossProduct(); } // This function calculates all of the vectors necessary for drawing a sloped and scaled plane. void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) { - floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; - fixed_t height, temp; + fixed_t height, z_at_xy; - float xscale = FixedToFloat(xs); - float yscale = FixedToFloat(ys); float ang; R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); height = P_GetSlopeZAt(slope, xpos, ypos); zeroheight = FixedToFloat(height - zpos); - // m is the v direction vector in view space ang = ANG2RAD(ANGLE_180 - (angle + plangle)); - m->x = yscale * cos(ang); - m->z = yscale * sin(ang); + + CalcSlopeLightVectors(slope, xpos, ypos, height, ang, plangle); + + if (ds_solidcolor || ds_fog) + { + DoSlopeLightCrossProduct(); + return; + } + + float xscale = FixedToFloat(xs); + float yscale = FixedToFloat(ys); + + // m is the v direction vector in view space + slope_v.x = yscale * cos(ang); + slope_v.z = yscale * sin(ang); // n is the u direction vector in view space - n->x = xscale * sin(ang); - n->z = -xscale * cos(ang); + slope_u.x = xscale * sin(ang); + slope_u.z = -xscale * cos(ang); ang = ANG2RAD(plangle); - temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(yscale * sin(ang)), ypos + FloatToFixed(yscale * cos(ang))); - m->y = FixedToFloat(temp - height); - temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(xscale * cos(ang)), ypos - FloatToFixed(xscale * sin(ang))); - n->y = FixedToFloat(temp - height); + z_at_xy = P_GetSlopeZAt(slope, xpos + FloatToFixed(yscale * sin(ang)), ypos + FloatToFixed(yscale * cos(ang))); + slope_v.y = FixedToFloat(z_at_xy - height); + z_at_xy = P_GetSlopeZAt(slope, xpos + FloatToFixed(xscale * cos(ang)), ypos - FloatToFixed(xscale * sin(ang))); + slope_u.y = FixedToFloat(z_at_xy - height); + + DoSlopeCrossProducts(); + DoSlopeLightCrossProduct(); } -void R_CalculateSlopeVectors(void) +static void CalcSlopeLightVectors(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t height, float ang, angle_t plangle) +{ + fixed_t z_at_xy; + + slope_lightv.x = cos(ang); + slope_lightv.z = sin(ang); + + slope_lightu.x = sin(ang); + slope_lightu.z = -cos(ang); + + plangle >>= ANGLETOFINESHIFT; + z_at_xy = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle)); + slope_lightv.y = FixedToFloat(z_at_xy - height); + z_at_xy = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle)); + slope_lightu.y = FixedToFloat(z_at_xy - height); +} + +// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. +#define CROSS(d, v1, v2) \ +d.x = (v1.y * v2.z) - (v1.z * v2.y);\ +d.y = (v1.z * v2.x) - (v1.x * v2.z);\ +d.z = (v1.x * v2.y) - (v1.y * v2.x) + +static void DoSlopeCrossProducts(void) { float sfmult = 65536.f; - // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. -#define CROSS(d, v1, v2) \ -d->x = (v1.y * v2.z) - (v1.z * v2.y);\ -d->y = (v1.z * v2.x) - (v1.x * v2.z);\ -d->z = (v1.x * v2.y) - (v1.y * v2.x) - CROSS(ds_sup, ds_slope_origin, ds_slope_v); - CROSS(ds_svp, ds_slope_origin, ds_slope_u); - CROSS(ds_szp, ds_slope_v, ds_slope_u); -#undef CROSS + CROSS(ds_su, slope_origin, slope_v); + CROSS(ds_sv, slope_origin, slope_u); + CROSS(ds_sz, slope_v, slope_u); - ds_sup->z *= focallengthf; - ds_svp->z *= focallengthf; - ds_szp->z *= focallengthf; + ds_su.z *= focallengthf; + ds_sv.z *= focallengthf; + ds_sz.z *= focallengthf; if (ds_solidcolor) return; // Premultiply the texture vectors with the scale factors if (ds_powersoftwo) - sfmult *= (1 << nflatshiftup); + sfmult *= 1 << nflatshiftup; - ds_sup->x *= sfmult; - ds_sup->y *= sfmult; - ds_sup->z *= sfmult; - ds_svp->x *= sfmult; - ds_svp->y *= sfmult; - ds_svp->z *= sfmult; + ds_su.x *= sfmult; + ds_su.y *= sfmult; + ds_su.z *= sfmult; + ds_sv.x *= sfmult; + ds_sv.y *= sfmult; + ds_sv.z *= sfmult; } -void R_SetTiltedSpan(INT32 span) +static void DoSlopeLightCrossProduct(void) { - if (ds_su == NULL) - ds_su = Z_Malloc(sizeof(*ds_su) * vid.height, PU_STATIC, NULL); - if (ds_sv == NULL) - ds_sv = Z_Malloc(sizeof(*ds_sv) * vid.height, PU_STATIC, NULL); - if (ds_sz == NULL) - ds_sz = Z_Malloc(sizeof(*ds_sz) * vid.height, PU_STATIC, NULL); + CROSS(ds_slopelight, slope_lightv, slope_lightu); - ds_sup = &ds_su[span]; - ds_svp = &ds_sv[span]; - ds_szp = &ds_sz[span]; + ds_slopelight.z *= focallengthf; } -static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff) -{ - R_SetTiltedSpan(y); +#undef CROSS - if (pl->xscale != FRACUNIT || pl->yscale != FRACUNIT) +static void CalcSlopePlaneVectors(visplane_t *pl, fixed_t xoff, fixed_t yoff) +{ + if (!ds_fog && (pl->xscale != FRACUNIT || pl->yscale != FRACUNIT)) { R_SetScaledSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, FixedDiv(FRACUNIT, pl->xscale), FixedDiv(FRACUNIT, pl->yscale), @@ -807,8 +835,6 @@ static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_ } else R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); - - R_CalculateSlopeVectors(); } static inline void R_AdjustSlopeCoordinates(vector3_t *origin) @@ -845,7 +871,6 @@ void R_DrawSinglePlane(visplane_t *pl) INT32 light = 0; INT32 x, stop; ffloor_t *rover; - boolean fog = false; INT32 spanfunctype = BASEDRAWFUNC; void (*mapfunc)(INT32, INT32, INT32); @@ -859,6 +884,8 @@ void R_DrawSinglePlane(visplane_t *pl) return; } + ds_powersoftwo = ds_solidcolor = ds_fog = false; + planeripple.active = false; if (pl->polyobj) @@ -923,13 +950,13 @@ void R_DrawSinglePlane(visplane_t *pl) } else if (pl->ffloor->fofflags & FOF_FOG) { - fog = true; + ds_fog = true; spanfunctype = SPANDRAWFUNC_FOG; light = (pl->lightlevel >> LIGHTSEGSHIFT); } else light = (pl->lightlevel >> LIGHTSEGSHIFT); - if (pl->ffloor->fofflags & FOF_RIPPLE && !fog) + if (pl->ffloor->fofflags & FOF_RIPPLE && !ds_fog) { planeripple.active = true; @@ -957,9 +984,7 @@ void R_DrawSinglePlane(visplane_t *pl) light = (pl->lightlevel >> LIGHTSEGSHIFT); } - ds_powersoftwo = ds_solidcolor = false; - - if (fog) + if (ds_fog) { // Since all fog planes do is apply a colormap, it's not required // to know any information about their textures. @@ -1025,7 +1050,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { - if (fog) + if (ds_fog) mapfunc = R_MapTiltedFogPlane; else { @@ -1040,21 +1065,10 @@ void R_DrawSinglePlane(visplane_t *pl) } } - if (planeripple.active) - { + if (!ds_fog && planeripple.active) planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); - - R_PlaneBounds(pl); - - for (x = pl->high; x < pl->low; x++) - { - ds_bgofs = R_CalculateRippleOffset(x); - R_CalculatePlaneRipple(pl->viewangle + pl->plangle); - R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac)); - } - } else - R_SetSlopePlaneVectors(pl, 0, xoffs, yoffs); + CalcSlopePlaneVectors(pl, xoffs, yoffs); switch (spanfunctype) { diff --git a/src/r_plane.h b/src/r_plane.h index 38d49d5db..5ce49e3cc 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -67,7 +67,6 @@ extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; extern fixed_t *yslope; extern lighttable_t **planezlight; -void R_InitPlanes(void); void R_ClearPlanes(void); void R_ClearFFloorClips (void); @@ -84,10 +83,6 @@ void R_DrawSinglePlane(visplane_t *pl); // Calculates the slope vectors needed for tilted span drawing. void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); -void R_CalculateSlopeVectors(void); - -// Sets the slope vector pointers for the current tilted span. -void R_SetTiltedSpan(INT32 span); typedef struct planemgr_s { diff --git a/src/r_splats.c b/src/r_splats.c index 9bfaa6b51..e9665e84a 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -369,7 +369,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr ds_flatwidth = pSplat->width; ds_flatheight = pSplat->height; - ds_powersoftwo = ds_solidcolor = false; + ds_powersoftwo = ds_solidcolor = ds_fog = false; if (R_CheckSolidColorFlat()) ds_solidcolor = true; @@ -381,9 +381,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (pSplat->slope) { - R_SetTiltedSpan(0); R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); - R_CalculateSlopeVectors(); } else if (!ds_solidcolor) { From e1e24cf53777bc8921cc1a88ad081f9d55a50f9a Mon Sep 17 00:00:00 2001 From: Hanicef Date: Mon, 25 Dec 2023 14:31:44 +0100 Subject: [PATCH 71/85] Make execinfo.h optional (fixes musl libc build) --- src/Makefile.d/features.mk | 2 +- src/sdl/i_system.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index 8b713718c..29587302f 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -5,7 +5,7 @@ passthru_opts+=\ NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ MOBJCONSISTANCY PACKETDROP ZDEBUG\ - HAVE_MINIUPNPC\ + HAVE_MINIUPNPC NOEXECINFO\ # build with debugging information ifdef DEBUGMODE diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 450237149..b1bde5226 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -138,7 +138,9 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#ifndef NOEXECINFO #include +#endif #include #define UNIXBACKTRACE #endif @@ -269,13 +271,17 @@ UINT8 keyboard_started = false; static void write_backtrace(INT32 signal) { int fd = -1; +#ifndef NOEXECINFO size_t size; +#endif time_t rawtime; struct tm timeinfo; ssize_t junk; enum { BT_SIZE = 1024, STR_SIZE = 32 }; +#ifndef NOEXECINFO void *array[BT_SIZE]; +#endif char timestr[STR_SIZE]; const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; @@ -308,12 +314,14 @@ static void write_backtrace(INT32 signal) CRASHLOG_WRITE(strsignal(signal)); CRASHLOG_WRITE("\n"); // Newline for the signal name +#ifndef NOEXECINFO CRASHLOG_STDERR_WRITE("\nBacktrace:\n"); // Flood the output and log with the backtrace size = backtrace(array, BT_SIZE); backtrace_symbols_fd(array, size, fd); backtrace_symbols_fd(array, size, STDERR_FILENO); +#endif CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :) (void)junk; From dbce1493eed0cef7280a440376d0b7767c48f3a9 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 25 Dec 2023 16:37:06 -0500 Subject: [PATCH 72/85] GitLab CI: Alpine 3 build job with GCC --- .gitlab-ci.yml | 131 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 49dd9bdf5..2b574ef39 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,6 +19,11 @@ default: - apt-cache unprotect: true + - key: apk-$CI_JOB_IMAGE + paths: + - apk-cache + unprotect: true + before_script: - - | # debconf @@ -503,3 +508,129 @@ Debian testing musl: CC: musl-gcc LDD: musl-ldd LDFLAGS: -Wl,-fuse-ld=gold + +Alpine 3 GCC: + stage: build + + when: manual + + image: alpine:3 + + allow_failure: true + + artifacts: + name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3-gcc" + + before_script: + - - | + # apk_cache + echo -e "\e[0Ksection_start:`date +%s`:apk_cache[collapsed=true]\r\e[0KUpdating APK listing" + - export APK_CACHE_DIR=`pwd`/apk-cache + - mkdir --parents --verbose $APK_CACHE_DIR/ + - ln -s /etc/apk/cache $APK_CACHE_DIR + - | + # apk_cache + echo -e "\e[0Ksection_end:`date +%s`:apk_cache\r\e[0K" + + - - | + # apk_update + echo -e "\e[0Ksection_start:`date +%s`:apk_update[collapsed=true]\r\e[0KUpdating APK listing" + - apk update + - | + # apk_update + echo -e "\e[0Ksection_end:`date +%s`:apk_update\r\e[0K" + + - - | + # apk_upgrade + echo -e "\e[0Ksection_start:`date +%s`:apk_upgrade[collapsed=true]\r\e[0KUpdating existing packages" + - apk upgrade + - | + # apk_update + echo -e "\e[0Ksection_end:`date +%s`:apk_upgrade\r\e[0K" + + - - | + # apk_common + echo -e "\e[0Ksection_start:`date +%s`:apk_common[collapsed=true]\r\e[0KInstalling common packages" + - apk add make git ccache nasm + - | + # apk_common + echo -e "\e[0Ksection_end:`date +%s`:apk_common\r\e[0K" + + - - | + # ccache_config + echo -e "\e[0Ksection_start:`date +%s`:ccache_config[collapsed=true]\r\e[0KSetting up ccache config" + - mkdir --parents --verbose ~/.ccache/ + - touch ~/.ccache/ccache.conf + - | + # cache.conf + echo Adding ccache configution option + - | + # base_dir + echo base_dir = $PWD | tee --append ~/.ccache/ccache.conf + - | + # cache_dir + echo cache_dir = $PWD/ccache | tee --append ~/.ccache/ccache.conf + - | + # compiler_check + echo compiler_check = content | tee --append ~/.ccache/ccache.conf + - | + # stats_log + echo stats_log = $PWD/ccache_statslog | tee --append ~/.ccache/ccache.conf + - | + # max_size + echo max_size = 50M | tee --append ~/.ccache/ccache.conf + - | + # ccache_config + echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K" + + - - | + # cache_reset + echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics" + - ccache --zero-stats + - ccache --show-stats + - | + # ccache_reset + echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\r\e[0K" + + script: + - - | + # apk_toolchain + echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages" + - apk add gcc + - | + # apk_toolchain + echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K" + + - - | + # apk_development + echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages" + - apk add musl-dev sdl2_mixer-dev libpng-dev curl-dev libgme-dev libopenmpt-dev + - | + # apk_development + echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K" + + - - | + # make + echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2" + - make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 + - | + # make + echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K" + + after_script: + - - | + # apk_clean + echo -e "\e[0Ksection_start:`date +%s`:apk_clean[collapsed=true]\r\e[0KCleaning of unneeded APK packages" + - apk cache clean + - | + # apk_clean + echo -e "\e[0Ksection_end:`date +%s`:apk_clean\r\e[0K" + + - - | + # ccache_stats + echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:" + - ccache --show-stats --verbose + - ccache --show-log-stats --verbose + - | + # ccahe_stats + echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K" From 13cfc5ef597f994b9100a21a1f0b2c6acca8fe75 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Mon, 25 Dec 2023 14:31:44 +0100 Subject: [PATCH 73/85] Make execinfo.h optional (fixes musl libc build) --- src/Makefile.d/features.mk | 2 +- src/sdl/i_system.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index a66779c07..20963adac 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -5,7 +5,7 @@ passthru_opts+=\ NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ MOBJCONSISTANCY PACKETDROP ZDEBUG\ - HAVE_MINIUPNPC\ + HAVE_MINIUPNPC NOEXECINFO\ # build with debugging information ifdef DEBUGMODE diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 2a26f3f50..dd0833f20 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -138,7 +138,9 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#ifndef NOEXECINFO #include +#endif #include #define UNIXBACKTRACE #endif @@ -268,13 +270,17 @@ UINT8 keyboard_started = false; static void write_backtrace(INT32 signal) { int fd = -1; +#ifndef NOEXECINFO size_t size; +#endif time_t rawtime; struct tm timeinfo; ssize_t junk; enum { BT_SIZE = 1024, STR_SIZE = 32 }; +#ifndef NOEXECINFO void *array[BT_SIZE]; +#endif char timestr[STR_SIZE]; const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; @@ -307,12 +313,14 @@ static void write_backtrace(INT32 signal) CRASHLOG_WRITE(strsignal(signal)); CRASHLOG_WRITE("\n"); // Newline for the signal name +#ifndef NOEXECINFO CRASHLOG_STDERR_WRITE("\nBacktrace:\n"); // Flood the output and log with the backtrace size = backtrace(array, BT_SIZE); backtrace_symbols_fd(array, size, fd); backtrace_symbols_fd(array, size, STDERR_FILENO); +#endif CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :) (void)junk; From 90f2170451a5a4b3c36b380020dcfb9c6bb30c0a Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 25 Dec 2023 16:51:59 -0500 Subject: [PATCH 74/85] GitLab CI: work with busybox's tee --- .gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2b574ef39..25ad113a7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -566,19 +566,19 @@ Alpine 3 GCC: echo Adding ccache configution option - | # base_dir - echo base_dir = $PWD | tee --append ~/.ccache/ccache.conf + echo base_dir = $PWD | tee -a ~/.ccache/ccache.conf - | # cache_dir - echo cache_dir = $PWD/ccache | tee --append ~/.ccache/ccache.conf + echo cache_dir = $PWD/ccache | tee -a ~/.ccache/ccache.conf - | # compiler_check - echo compiler_check = content | tee --append ~/.ccache/ccache.conf + echo compiler_check = content | tee -a ~/.ccache/ccache.conf - | # stats_log - echo stats_log = $PWD/ccache_statslog | tee --append ~/.ccache/ccache.conf + echo stats_log = $PWD/ccache_statslog | tee -a ~/.ccache/ccache.conf - | # max_size - echo max_size = 50M | tee --append ~/.ccache/ccache.conf + echo max_size = 50M | tee -a ~/.ccache/ccache.conf - | # ccache_config echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K" From d678237a5c48d92c25a95235b5f6f6cd1f0b5171 Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Mon, 25 Dec 2023 21:59:28 +0000 Subject: [PATCH 75/85] Update .gitlab-ci.yml file add NOEXECINFO=1 to make --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 25ad113a7..16179b6ba 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -612,7 +612,7 @@ Alpine 3 GCC: - - | # make echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2" - - make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 + - make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 - | # make echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K" From e1f2cbd8ad178496ec3a012366b3c432f4bd71f0 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 25 Dec 2023 17:21:34 -0500 Subject: [PATCH 76/85] GitLab-CI: fixup artifact exposes --- .gitlab-ci.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 16179b6ba..f288b36c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -172,6 +172,10 @@ Debian testing GCC: allow_failure: true artifacts: + paths: + - "bin/" + - "src/comptime.h" + expose_as: "testing-gcc" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-gcc" variables: @@ -406,6 +410,10 @@ Debian stable Clang: allow_failure: true artifacts: + paths: + - "bin/" + - "src/comptime.h" + expose_as: "clang" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang" variables: @@ -447,6 +455,10 @@ Debian stable musl: allow_failure: true artifacts: + paths: + - "bin/" + - "src/comptime.h" + expose_as: "musl" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-musl" variables: @@ -486,6 +498,10 @@ Debian testing Clang: image: debian:testing-slim artifacts: + paths: + - "bin/" + - "src/comptime.h" + expose_as: "testing-clang" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang" variables: @@ -502,6 +518,10 @@ Debian testing musl: image: debian:testing-slim artifacts: + paths: + - "bin/" + - "src/comptime.h" + expose_as: "testing-musl" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-musl" variables: @@ -519,7 +539,11 @@ Alpine 3 GCC: allow_failure: true artifacts: - name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3-gcc" + paths: + - "bin/" + - "src/comptime.h" + expose_as: "Apline-3" + name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3" before_script: - - | From 78af4afc0631fb8a14ebbc2095f7b6d0464d580c Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 25 Dec 2023 17:27:50 -0500 Subject: [PATCH 77/85] GitLab-CI: builders may reuse jobs, force remake links --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f288b36c9..8bfe4fb36 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -551,7 +551,7 @@ Alpine 3 GCC: echo -e "\e[0Ksection_start:`date +%s`:apk_cache[collapsed=true]\r\e[0KUpdating APK listing" - export APK_CACHE_DIR=`pwd`/apk-cache - mkdir --parents --verbose $APK_CACHE_DIR/ - - ln -s /etc/apk/cache $APK_CACHE_DIR + - ln -sf /etc/apk/cache $APK_CACHE_DIR - | # apk_cache echo -e "\e[0Ksection_end:`date +%s`:apk_cache\r\e[0K" From 90edfa562df3c7bafd42e29bb87e320ebc67b35d Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 25 Dec 2023 17:37:29 -0500 Subject: [PATCH 78/85] GitLib-CI: let use this build job to keep us from breaking non-glibc systems --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8bfe4fb36..46fa6584d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -532,7 +532,7 @@ Debian testing musl: Alpine 3 GCC: stage: build - when: manual + when: on_success image: alpine:3 From 6c701a93120d4f48ab170df1e4a0f558dd686aee Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Tue, 26 Dec 2023 19:21:09 +0000 Subject: [PATCH 79/85] Revert "Merge branch 'native-keyboard-layout-support' into 'next'" This reverts merge request !1952 --- src/console.c | 19 +++++++----- src/d_event.h | 1 - src/d_main.c | 6 ++-- src/hu_stuff.c | 60 ++++++++++++++++-------------------- src/m_menu.c | 76 ++++++++++++++++++++-------------------------- src/sdl/i_system.c | 1 - src/sdl/i_video.c | 16 ---------- 7 files changed, 74 insertions(+), 105 deletions(-) diff --git a/src/console.c b/src/console.c index cdb1fc196..01b90ebc3 100644 --- a/src/console.c +++ b/src/console.c @@ -937,7 +937,7 @@ boolean CON_Responder(event_t *ev) return false; // let go keyup events, don't eat them - if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console) + if (ev->type != ev_keydown && ev->type != ev_console) { if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1]) consdown = false; @@ -964,7 +964,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (ev->type == ev_keydown && !menuactive && bindtable[key]) + if (! menuactive && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); @@ -981,12 +981,6 @@ boolean CON_Responder(event_t *ev) } } - if (ev->type == ev_text) - { - CON_InputAddChar(key); - return true; - } - // Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas if (key == KEY_LSHIFT || key == KEY_RSHIFT || key == KEY_LCTRL || key == KEY_RCTRL @@ -1301,12 +1295,21 @@ boolean CON_Responder(event_t *ev) else if (key == KEY_KPADSLASH) key = '/'; + if (key >= 'a' && key <= 'z') + { + if (capslock ^ shiftdown) + key = shiftxform[key]; + } + else if (shiftdown) + key = shiftxform[key]; + // enter a char into the command prompt if (key < 32 || key > 127) return true; if (input_sel != input_cur) CON_InputDelSelection(); + CON_InputAddChar(key); return true; } diff --git a/src/d_event.h b/src/d_event.h index 7743d8609..5aa435060 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -22,7 +22,6 @@ typedef enum { ev_keydown, ev_keyup, - ev_text, ev_console, ev_mouse, ev_joystick, diff --git a/src/d_main.c b/src/d_main.c index bc821cf71..274e4ceb3 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -192,19 +192,19 @@ void D_ProcessEvents(void) ev = &events[eventtail]; // Set mouse buttons early in case event is eaten later - if (ev->type == ev_keydown || ev->type == ev_keyup || ev->type == ev_text) + if (ev->type == ev_keydown || ev->type == ev_keyup) { // Mouse buttons if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS) { - if (ev->type == ev_keydown || ev->type == ev_text) + if (ev->type == ev_keydown) mouse.buttons |= 1 << (ev->key - KEY_MOUSE1); else mouse.buttons &= ~(1 << (ev->key - KEY_MOUSE1)); } else if ((UINT32)(ev->key - KEY_2MOUSE1) < MOUSEBUTTONS) { - if (ev->type == ev_keydown || ev->type == ev_text) + if (ev->type == ev_keydown) mouse2.buttons |= 1 << (ev->key - KEY_2MOUSE1); else mouse2.buttons &= ~(1 << (ev->key - KEY_2MOUSE1)); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 0a2b71aec..6178298d2 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -79,7 +79,6 @@ patch_t *nto_font[NT_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? -boolean chat_on_first_event; // blocker for first chat input event static char w_chat[HU_MAXMSGLEN + 1]; static size_t c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; @@ -1040,7 +1039,7 @@ boolean HU_Responder(event_t *ev) { INT32 c=0; - if (ev->type != ev_keydown && ev->type != ev_text) + if (ev->type != ev_keydown) return false; // only KeyDown events now... @@ -1069,15 +1068,11 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { - if (ev->type == ev_text) - return false; - // enter chat mode if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1]) && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. { chat_on = true; - chat_on_first_event = false; w_chat[0] = 0; teamtalk = false; chat_scrollmedown = true; @@ -1088,7 +1083,6 @@ boolean HU_Responder(event_t *ev) && netgame && !OLD_MUTE) { chat_on = true; - chat_on_first_event = false; w_chat[0] = 0; teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams. chat_scrollmedown = true; @@ -1098,31 +1092,6 @@ boolean HU_Responder(event_t *ev) } else // if chat_on { - if (!chat_on_first_event) - { - // since the text event is sent immediately after the keydown event, - // we need to make sure that nothing is displayed once the chat - // opens, otherwise a 't' would be outputted. - chat_on_first_event = true; - return true; - } - - if (ev->type == ev_text) - { - if ((c < HU_FONTSTART || c > HU_FONTEND || !hu_font[c-HU_FONTSTART]) - && c != ' ') // Allow spaces, of course - { - return false; - } - - if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN) - return true; - - memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1); - w_chat[c_input] = c; - c_input++; - return true; - } // Ignore modifier keys // Note that we do this here so users can still set @@ -1132,8 +1101,23 @@ boolean HU_Responder(event_t *ev) || ev->key == KEY_LALT || ev->key == KEY_RALT) return true; + c = (INT32)ev->key; + + // I know this looks very messy but this works. If it ain't broke, don't fix it! + // shift LETTERS to uppercase if we have capslock or are holding shift + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + { + if (shiftdown ^ capslock) + c = shiftxform[c]; + } + else // if we're holding shift we should still shift non letter symbols + { + if (shiftdown) + c = shiftxform[c]; + } + // pasting. pasting is cool. chat is a bit limited, though :( - if (c == 'v' && ctrldown) + if ((c == 'v' || c == 'V') && ctrldown) { const char *paste; size_t chatlen; @@ -1201,6 +1185,16 @@ boolean HU_Responder(event_t *ev) else c_input++; } + else if ((c >= HU_FONTSTART && c <= HU_FONTEND && hu_font[c-HU_FONTSTART]) + || c == ' ') // Allow spaces, of course + { + if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN) + return true; + + memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1); + w_chat[c_input] = c; + c_input++; + } else if (c == KEY_BACKSPACE) { if (CHAT_MUTE || c_input <= 0) diff --git a/src/m_menu.c b/src/m_menu.c index 9aae59445..72d4547b0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3177,42 +3177,40 @@ boolean M_Responder(event_t *ev) } else if (menuactive) { - if (ev->type == ev_keydown || ev->type == ev_text) + if (ev->type == ev_keydown) { + keydown++; ch = ev->key; - if (ev->type == ev_keydown) + + // added 5-2-98 remap virtual keys (mouse & joystick buttons) + switch (ch) { - keydown++; - // added 5-2-98 remap virtual keys (mouse & joystick buttons) - switch (ch) - { - case KEY_MOUSE1: - case KEY_JOY1: - ch = KEY_ENTER; - break; - case KEY_JOY1 + 3: - ch = 'n'; - break; - case KEY_MOUSE1 + 1: - case KEY_JOY1 + 1: - ch = KEY_ESCAPE; - break; - case KEY_JOY1 + 2: - ch = KEY_BACKSPACE; - break; - case KEY_HAT1: - ch = KEY_UPARROW; - break; - case KEY_HAT1 + 1: - ch = KEY_DOWNARROW; - break; - case KEY_HAT1 + 2: - ch = KEY_LEFTARROW; - break; - case KEY_HAT1 + 3: - ch = KEY_RIGHTARROW; - break; - } + case KEY_MOUSE1: + case KEY_JOY1: + ch = KEY_ENTER; + break; + case KEY_JOY1 + 3: + ch = 'n'; + break; + case KEY_MOUSE1 + 1: + case KEY_JOY1 + 1: + ch = KEY_ESCAPE; + break; + case KEY_JOY1 + 2: + ch = KEY_BACKSPACE; + break; + case KEY_HAT1: + ch = KEY_UPARROW; + break; + case KEY_HAT1 + 1: + ch = KEY_DOWNARROW; + break; + case KEY_HAT1 + 2: + ch = KEY_LEFTARROW; + break; + case KEY_HAT1 + 3: + ch = KEY_RIGHTARROW; + break; } } else if (ev->type == ev_joystick && ev->key == 0 && joywait < I_GetTime()) @@ -3374,11 +3372,8 @@ boolean M_Responder(event_t *ev) // Handle menuitems which need a specific key handling if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) { - // ignore ev_keydown events if the key maps to a character, since - // the ev_text event will follow immediately after in that case. - if (ev->type == ev_keydown && ch >= 32 && ch <= 127) - return true; - + if (shiftdown && ch >= 32 && ch <= 127) + ch = shiftxform[ch]; routine(ch); return true; } @@ -3420,11 +3415,6 @@ boolean M_Responder(event_t *ev) { if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING) { - // ignore ev_keydown events if the key maps to a character, since - // the ev_text event will follow immediately after in that case. - if (ev->type == ev_keydown && ch >= 32 && ch <= 127) - return false; - if (M_ChangeStringCvar(ch)) return true; else diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 847806270..986647e72 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -652,7 +652,6 @@ void I_GetConsoleEvents(void) else if (tty_con.cursor < sizeof (tty_con.buffer)) { // push regular character - ev.type = ev_text; ev.key = tty_con.buffer[tty_con.cursor] = key; tty_con.cursor++; // print the current line (this is differential) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d3a602c05..a70e5a860 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -693,19 +693,6 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) if (event.key) D_PostEvent(&event); } -static void Impl_HandleTextEvent(SDL_TextInputEvent evt) -{ - event_t event; - event.type = ev_text; - if (evt.text[1] != '\0') - { - // limit ourselves to ASCII for now, we can add UTF-8 support later - return; - } - event.key = evt.text[0]; - D_PostEvent(&event); -} - static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) { static boolean firstmove = true; @@ -954,9 +941,6 @@ void I_GetEvent(void) case SDL_KEYDOWN: Impl_HandleKeyboardEvent(evt.key, evt.type); break; - case SDL_TEXTINPUT: - Impl_HandleTextEvent(evt.text); - break; case SDL_MOUSEMOTION: //if (!mouseMotionOnce) Impl_HandleMouseMotionEvent(evt.motion); From 3ae6a99ac70753c3bb8943b726e4f4c2a94bf61e Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Tue, 26 Dec 2023 19:32:40 +0000 Subject: [PATCH 80/85] Revert "Merge branch 'allow-multiple-admin-passwords' into 'next'" This reverts merge request !2201 --- src/netcode/d_clisrv.c | 27 +++++++++++---------------- src/netcode/d_clisrv.h | 4 ++-- src/netcode/d_netcmd.c | 35 ++++------------------------------- src/netcode/d_netcmd.h | 1 - 4 files changed, 17 insertions(+), 50 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index d222920c3..ac0b42d49 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -90,8 +90,8 @@ INT16 consistancy[BACKUPTICS]; // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks boolean hu_stopped = false; -UINT8 (*adminpassmd5)[16]; -UINT32 adminpasscount = 0; +UINT8 adminpassmd5[16]; +boolean adminpasswordset = false; tic_t neededtic; SINT8 servernode = 0; // the number of the server node @@ -862,31 +862,26 @@ static void PT_Login(SINT8 node, INT32 netconsole) #ifndef NOMD5 UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ - UINT32 i; if (doomcom->datalength < 16)/* ignore partial sends */ return; - if (adminpasscount == 0) + if (!adminpasswordset) { CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); return; } - for (i = 0; i < adminpasscount; i++) + // Do the final pass to compare with the sent md5 + D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5); + + if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) { - // Do the final pass to compare with the sent md5 - D_MD5PasswordPass(adminpassmd5[i], 16, va("PNUM%02d", netconsole), &finalmd5); - - if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) - { - CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); - COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately - return; - } + CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); + COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately } - - CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); + else + CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); #else (void)netconsole; #endif diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index f9cbf8876..092878421 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -128,8 +128,8 @@ tic_t GetLag(INT32 node); void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest); -extern UINT8 (*adminpassmd5)[16]; -extern UINT32 adminpasscount; +extern UINT8 adminpassmd5[16]; +extern boolean adminpasswordset; extern boolean hu_stopped; diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index ef1ef9aeb..2b445a835 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -150,7 +150,6 @@ static void Command_Clearscores_f(void); // Remote Administration static void Command_Changepassword_f(void); -static void Command_Clearpassword_f(void); static void Command_Login_f(void); static void Got_Verification(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum); @@ -469,7 +468,6 @@ void D_RegisterServerCommands(void) // Remote Administration COM_AddCommand("password", Command_Changepassword_f, COM_LUA); - COM_AddCommand("clearpassword", Command_Clearpassword_f, COM_LUA); COM_AddCommand("login", Command_Login_f, COM_LUA); // useful in dedicated to kick off remote admin COM_AddCommand("promote", Command_Verify_f, COM_LUA); RegisterNetXCmd(XD_VERIFIED, Got_Verification); @@ -2846,15 +2844,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) void D_SetPassword(const char *pw) { - adminpassmd5 = Z_Realloc(adminpassmd5, sizeof(*adminpassmd5) * ++adminpasscount, PU_STATIC, NULL); - D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5[adminpasscount-1]); -} - -void D_ClearPassword(void) -{ - Z_Free(adminpassmd5); - adminpassmd5 = NULL; - adminpasscount = 0; + D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5); + adminpasswordset = true; } // Remote Administration @@ -2872,30 +2863,12 @@ static void Command_Changepassword_f(void) if (COM_Argc() != 2) { - CONS_Printf(M_GetText("password : add remote admin password\n")); + CONS_Printf(M_GetText("password : change remote admin password\n")); return; } D_SetPassword(COM_Argv(1)); - CONS_Printf(M_GetText("Password added.\n")); -#endif -} - -// Remote Administration -static void Command_Clearpassword_f(void) -{ -#ifdef NOMD5 - // If we have no MD5 support then completely disable XD_LOGIN responses for security. - CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n"); -#else - if (client) // cannot change remotely - { - CONS_Printf(M_GetText("Only the server can use this.\n")); - return; - } - - D_ClearPassword(); - CONS_Printf(M_GetText("Passwords cleared.\n")); + CONS_Printf(M_GetText("Password set.\n")); #endif } diff --git a/src/netcode/d_netcmd.h b/src/netcode/d_netcmd.h index 0f2a1f92b..4849079d0 100644 --- a/src/netcode/d_netcmd.h +++ b/src/netcode/d_netcmd.h @@ -209,7 +209,6 @@ void ClearAdminPlayers(void); void RemoveAdminPlayer(INT32 playernum); void ItemFinder_OnChange(void); void D_SetPassword(const char *pw); -void D_ClearPassword(void); // used for the player setup menu UINT8 CanChangeSkin(INT32 playernum); From 80af2a27d4f14d9b0ab6a1f7655f9c3e94be0332 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 26 Dec 2023 17:14:30 -0300 Subject: [PATCH 81/85] Fix -Warray-bounds warning in lua_hooklib.c --- src/lua_hooklib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 0fc25ee6c..38815a06c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -76,12 +76,12 @@ static boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type) ); } -static int hook_in_list +static unsigned hook_in_list ( const char * const name, const char * const * const list ){ - int type; + unsigned type; for (type = 0; list[type] != NULL; ++type) { @@ -200,7 +200,7 @@ static void add_hook_ref(lua_State *L, int idx) static int lib_addHook(lua_State *L) { const char * name; - int type; + unsigned type; if (!lua_lumploading) return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); From fa0c5cfd04e62038684febd1cf42fd70232b228b Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 26 Dec 2023 17:20:57 -0300 Subject: [PATCH 82/85] Revert 3ae6a99ac70753c3bb8943b726e4f4c2a94bf61e --- src/netcode/d_clisrv.c | 27 ++++++++++++++++----------- src/netcode/d_clisrv.h | 4 ++-- src/netcode/d_netcmd.c | 35 +++++++++++++++++++++++++++++++---- src/netcode/d_netcmd.h | 1 + 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index ac0b42d49..d222920c3 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -90,8 +90,8 @@ INT16 consistancy[BACKUPTICS]; // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks boolean hu_stopped = false; -UINT8 adminpassmd5[16]; -boolean adminpasswordset = false; +UINT8 (*adminpassmd5)[16]; +UINT32 adminpasscount = 0; tic_t neededtic; SINT8 servernode = 0; // the number of the server node @@ -862,26 +862,31 @@ static void PT_Login(SINT8 node, INT32 netconsole) #ifndef NOMD5 UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ + UINT32 i; if (doomcom->datalength < 16)/* ignore partial sends */ return; - if (!adminpasswordset) + if (adminpasscount == 0) { CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); return; } - // Do the final pass to compare with the sent md5 - D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5); - - if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) + for (i = 0; i < adminpasscount; i++) { - CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); - COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately + // Do the final pass to compare with the sent md5 + D_MD5PasswordPass(adminpassmd5[i], 16, va("PNUM%02d", netconsole), &finalmd5); + + if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) + { + CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); + COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately + return; + } } - else - CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); + + CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); #else (void)netconsole; #endif diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index 092878421..f9cbf8876 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -128,8 +128,8 @@ tic_t GetLag(INT32 node); void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest); -extern UINT8 adminpassmd5[16]; -extern boolean adminpasswordset; +extern UINT8 (*adminpassmd5)[16]; +extern UINT32 adminpasscount; extern boolean hu_stopped; diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 2b445a835..ef1ef9aeb 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -150,6 +150,7 @@ static void Command_Clearscores_f(void); // Remote Administration static void Command_Changepassword_f(void); +static void Command_Clearpassword_f(void); static void Command_Login_f(void); static void Got_Verification(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum); @@ -468,6 +469,7 @@ void D_RegisterServerCommands(void) // Remote Administration COM_AddCommand("password", Command_Changepassword_f, COM_LUA); + COM_AddCommand("clearpassword", Command_Clearpassword_f, COM_LUA); COM_AddCommand("login", Command_Login_f, COM_LUA); // useful in dedicated to kick off remote admin COM_AddCommand("promote", Command_Verify_f, COM_LUA); RegisterNetXCmd(XD_VERIFIED, Got_Verification); @@ -2844,8 +2846,15 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) void D_SetPassword(const char *pw) { - D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5); - adminpasswordset = true; + adminpassmd5 = Z_Realloc(adminpassmd5, sizeof(*adminpassmd5) * ++adminpasscount, PU_STATIC, NULL); + D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5[adminpasscount-1]); +} + +void D_ClearPassword(void) +{ + Z_Free(adminpassmd5); + adminpassmd5 = NULL; + adminpasscount = 0; } // Remote Administration @@ -2863,12 +2872,30 @@ static void Command_Changepassword_f(void) if (COM_Argc() != 2) { - CONS_Printf(M_GetText("password : change remote admin password\n")); + CONS_Printf(M_GetText("password : add remote admin password\n")); return; } D_SetPassword(COM_Argv(1)); - CONS_Printf(M_GetText("Password set.\n")); + CONS_Printf(M_GetText("Password added.\n")); +#endif +} + +// Remote Administration +static void Command_Clearpassword_f(void) +{ +#ifdef NOMD5 + // If we have no MD5 support then completely disable XD_LOGIN responses for security. + CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n"); +#else + if (client) // cannot change remotely + { + CONS_Printf(M_GetText("Only the server can use this.\n")); + return; + } + + D_ClearPassword(); + CONS_Printf(M_GetText("Passwords cleared.\n")); #endif } diff --git a/src/netcode/d_netcmd.h b/src/netcode/d_netcmd.h index 4849079d0..0f2a1f92b 100644 --- a/src/netcode/d_netcmd.h +++ b/src/netcode/d_netcmd.h @@ -209,6 +209,7 @@ void ClearAdminPlayers(void); void RemoveAdminPlayer(INT32 playernum); void ItemFinder_OnChange(void); void D_SetPassword(const char *pw); +void D_ClearPassword(void); // used for the player setup menu UINT8 CanChangeSkin(INT32 playernum); From a266fbb6a055e2aec20a931200a3604f7e0a1033 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 26 Dec 2023 17:53:38 -0300 Subject: [PATCH 83/85] Revert 6c701a93120d4f48ab170df1e4a0f558dd686aee --- src/console.c | 19 +++++------- src/d_event.h | 1 + src/d_main.c | 6 ++-- src/hu_stuff.c | 60 ++++++++++++++++++++---------------- src/m_menu.c | 76 ++++++++++++++++++++++++++-------------------- src/sdl/i_system.c | 1 + src/sdl/i_video.c | 16 ++++++++++ 7 files changed, 105 insertions(+), 74 deletions(-) diff --git a/src/console.c b/src/console.c index 01b90ebc3..cdb1fc196 100644 --- a/src/console.c +++ b/src/console.c @@ -937,7 +937,7 @@ boolean CON_Responder(event_t *ev) return false; // let go keyup events, don't eat them - if (ev->type != ev_keydown && ev->type != ev_console) + if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console) { if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1]) consdown = false; @@ -964,7 +964,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (! menuactive && bindtable[key]) + if (ev->type == ev_keydown && !menuactive && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); @@ -981,6 +981,12 @@ boolean CON_Responder(event_t *ev) } } + if (ev->type == ev_text) + { + CON_InputAddChar(key); + return true; + } + // Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas if (key == KEY_LSHIFT || key == KEY_RSHIFT || key == KEY_LCTRL || key == KEY_RCTRL @@ -1295,21 +1301,12 @@ boolean CON_Responder(event_t *ev) else if (key == KEY_KPADSLASH) key = '/'; - if (key >= 'a' && key <= 'z') - { - if (capslock ^ shiftdown) - key = shiftxform[key]; - } - else if (shiftdown) - key = shiftxform[key]; - // enter a char into the command prompt if (key < 32 || key > 127) return true; if (input_sel != input_cur) CON_InputDelSelection(); - CON_InputAddChar(key); return true; } diff --git a/src/d_event.h b/src/d_event.h index 5aa435060..7743d8609 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -22,6 +22,7 @@ typedef enum { ev_keydown, ev_keyup, + ev_text, ev_console, ev_mouse, ev_joystick, diff --git a/src/d_main.c b/src/d_main.c index 274e4ceb3..bc821cf71 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -192,19 +192,19 @@ void D_ProcessEvents(void) ev = &events[eventtail]; // Set mouse buttons early in case event is eaten later - if (ev->type == ev_keydown || ev->type == ev_keyup) + if (ev->type == ev_keydown || ev->type == ev_keyup || ev->type == ev_text) { // Mouse buttons if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) mouse.buttons |= 1 << (ev->key - KEY_MOUSE1); else mouse.buttons &= ~(1 << (ev->key - KEY_MOUSE1)); } else if ((UINT32)(ev->key - KEY_2MOUSE1) < MOUSEBUTTONS) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) mouse2.buttons |= 1 << (ev->key - KEY_2MOUSE1); else mouse2.buttons &= ~(1 << (ev->key - KEY_2MOUSE1)); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6178298d2..0a2b71aec 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -79,6 +79,7 @@ patch_t *nto_font[NT_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? +boolean chat_on_first_event; // blocker for first chat input event static char w_chat[HU_MAXMSGLEN + 1]; static size_t c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; @@ -1039,7 +1040,7 @@ boolean HU_Responder(event_t *ev) { INT32 c=0; - if (ev->type != ev_keydown) + if (ev->type != ev_keydown && ev->type != ev_text) return false; // only KeyDown events now... @@ -1068,11 +1069,15 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { + if (ev->type == ev_text) + return false; + // enter chat mode if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1]) && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. { chat_on = true; + chat_on_first_event = false; w_chat[0] = 0; teamtalk = false; chat_scrollmedown = true; @@ -1083,6 +1088,7 @@ boolean HU_Responder(event_t *ev) && netgame && !OLD_MUTE) { chat_on = true; + chat_on_first_event = false; w_chat[0] = 0; teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams. chat_scrollmedown = true; @@ -1092,6 +1098,31 @@ boolean HU_Responder(event_t *ev) } else // if chat_on { + if (!chat_on_first_event) + { + // since the text event is sent immediately after the keydown event, + // we need to make sure that nothing is displayed once the chat + // opens, otherwise a 't' would be outputted. + chat_on_first_event = true; + return true; + } + + if (ev->type == ev_text) + { + if ((c < HU_FONTSTART || c > HU_FONTEND || !hu_font[c-HU_FONTSTART]) + && c != ' ') // Allow spaces, of course + { + return false; + } + + if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN) + return true; + + memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1); + w_chat[c_input] = c; + c_input++; + return true; + } // Ignore modifier keys // Note that we do this here so users can still set @@ -1101,23 +1132,8 @@ boolean HU_Responder(event_t *ev) || ev->key == KEY_LALT || ev->key == KEY_RALT) return true; - c = (INT32)ev->key; - - // I know this looks very messy but this works. If it ain't broke, don't fix it! - // shift LETTERS to uppercase if we have capslock or are holding shift - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - if (shiftdown ^ capslock) - c = shiftxform[c]; - } - else // if we're holding shift we should still shift non letter symbols - { - if (shiftdown) - c = shiftxform[c]; - } - // pasting. pasting is cool. chat is a bit limited, though :( - if ((c == 'v' || c == 'V') && ctrldown) + if (c == 'v' && ctrldown) { const char *paste; size_t chatlen; @@ -1185,16 +1201,6 @@ boolean HU_Responder(event_t *ev) else c_input++; } - else if ((c >= HU_FONTSTART && c <= HU_FONTEND && hu_font[c-HU_FONTSTART]) - || c == ' ') // Allow spaces, of course - { - if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN) - return true; - - memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1); - w_chat[c_input] = c; - c_input++; - } else if (c == KEY_BACKSPACE) { if (CHAT_MUTE || c_input <= 0) diff --git a/src/m_menu.c b/src/m_menu.c index 72d4547b0..9aae59445 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3177,40 +3177,42 @@ boolean M_Responder(event_t *ev) } else if (menuactive) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) { - keydown++; ch = ev->key; - - // added 5-2-98 remap virtual keys (mouse & joystick buttons) - switch (ch) + if (ev->type == ev_keydown) { - case KEY_MOUSE1: - case KEY_JOY1: - ch = KEY_ENTER; - break; - case KEY_JOY1 + 3: - ch = 'n'; - break; - case KEY_MOUSE1 + 1: - case KEY_JOY1 + 1: - ch = KEY_ESCAPE; - break; - case KEY_JOY1 + 2: - ch = KEY_BACKSPACE; - break; - case KEY_HAT1: - ch = KEY_UPARROW; - break; - case KEY_HAT1 + 1: - ch = KEY_DOWNARROW; - break; - case KEY_HAT1 + 2: - ch = KEY_LEFTARROW; - break; - case KEY_HAT1 + 3: - ch = KEY_RIGHTARROW; - break; + keydown++; + // added 5-2-98 remap virtual keys (mouse & joystick buttons) + switch (ch) + { + case KEY_MOUSE1: + case KEY_JOY1: + ch = KEY_ENTER; + break; + case KEY_JOY1 + 3: + ch = 'n'; + break; + case KEY_MOUSE1 + 1: + case KEY_JOY1 + 1: + ch = KEY_ESCAPE; + break; + case KEY_JOY1 + 2: + ch = KEY_BACKSPACE; + break; + case KEY_HAT1: + ch = KEY_UPARROW; + break; + case KEY_HAT1 + 1: + ch = KEY_DOWNARROW; + break; + case KEY_HAT1 + 2: + ch = KEY_LEFTARROW; + break; + case KEY_HAT1 + 3: + ch = KEY_RIGHTARROW; + break; + } } } else if (ev->type == ev_joystick && ev->key == 0 && joywait < I_GetTime()) @@ -3372,8 +3374,11 @@ boolean M_Responder(event_t *ev) // Handle menuitems which need a specific key handling if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) { - if (shiftdown && ch >= 32 && ch <= 127) - ch = shiftxform[ch]; + // ignore ev_keydown events if the key maps to a character, since + // the ev_text event will follow immediately after in that case. + if (ev->type == ev_keydown && ch >= 32 && ch <= 127) + return true; + routine(ch); return true; } @@ -3415,6 +3420,11 @@ boolean M_Responder(event_t *ev) { if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING) { + // ignore ev_keydown events if the key maps to a character, since + // the ev_text event will follow immediately after in that case. + if (ev->type == ev_keydown && ch >= 32 && ch <= 127) + return false; + if (M_ChangeStringCvar(ch)) return true; else diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 986647e72..847806270 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -652,6 +652,7 @@ void I_GetConsoleEvents(void) else if (tty_con.cursor < sizeof (tty_con.buffer)) { // push regular character + ev.type = ev_text; ev.key = tty_con.buffer[tty_con.cursor] = key; tty_con.cursor++; // print the current line (this is differential) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index a70e5a860..d3a602c05 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -693,6 +693,19 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) if (event.key) D_PostEvent(&event); } +static void Impl_HandleTextEvent(SDL_TextInputEvent evt) +{ + event_t event; + event.type = ev_text; + if (evt.text[1] != '\0') + { + // limit ourselves to ASCII for now, we can add UTF-8 support later + return; + } + event.key = evt.text[0]; + D_PostEvent(&event); +} + static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) { static boolean firstmove = true; @@ -941,6 +954,9 @@ void I_GetEvent(void) case SDL_KEYDOWN: Impl_HandleKeyboardEvent(evt.key, evt.type); break; + case SDL_TEXTINPUT: + Impl_HandleTextEvent(evt.text); + break; case SDL_MOUSEMOTION: //if (!mouseMotionOnce) Impl_HandleMouseMotionEvent(evt.motion); From 1f65c5507419ded1ec143e5d52f3f4532b8e81de Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 26 Dec 2023 18:29:41 -0300 Subject: [PATCH 84/85] Don't add text to the console on the same frame it's being toggled Resolves #1161 --- src/console.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index cdb1fc196..ece1e9727 100644 --- a/src/console.c +++ b/src/console.c @@ -983,7 +983,8 @@ boolean CON_Responder(event_t *ev) if (ev->type == ev_text) { - CON_InputAddChar(key); + if (!consoletoggle) + CON_InputAddChar(key); return true; } From 2ef5ea86f3956f6a34fe6860ae1180fd4d2e63d0 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 26 Dec 2023 18:31:11 -0300 Subject: [PATCH 85/85] Don't toggle the console if shift is held --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index ece1e9727..706ed6633 100644 --- a/src/console.c +++ b/src/console.c @@ -952,7 +952,7 @@ boolean CON_Responder(event_t *ev) if (modeattacking || metalrecording || marathonmode) return false; - if (key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) + if ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown) { if (consdown) // ignore repeat return true;