From 564d18b1eac5928daee834f958e1283719ddf655 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Tue, 2 Jan 2024 17:51:43 +0100 Subject: [PATCH 01/18] Add and use an "instant" parameter for P_SetScale --- src/b_bot.c | 3 +- src/g_demo.c | 12 ++-- src/lua_baselib.c | 3 +- src/lua_mobjlib.c | 6 +- src/p_enemy.c | 150 ++++++++++++++++++-------------------- src/p_inter.c | 18 ++--- src/p_mobj.c | 178 ++++++++++++++++++++-------------------------- src/p_mobj.h | 2 +- src/p_user.c | 78 ++++++++------------ src/r_skins.c | 2 +- 10 files changed, 194 insertions(+), 258 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index c8228e840..af57d65ec 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -589,8 +589,9 @@ void B_RespawnBot(INT32 playernum) } else P_SetMobjState(tails, S_PLAY_FALL); - P_SetScale(tails, sonic->scale); + P_SetScale(tails, sonic->scale, false); tails->destscale = sonic->destscale; + tails->old_scale = sonic->old_scale; } void B_HandleFlightIndicator(player_t *player) diff --git a/src/g_demo.c b/src/g_demo.c index c30b07f25..f980d3063 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -771,7 +771,7 @@ void G_GhostTicker(void) { g->mo->destscale = READFIXED(g->p); if (g->mo->destscale != g->mo->scale) - P_SetScale(g->mo, g->mo->destscale); + P_SetScale(g->mo, g->mo->destscale, false); } if (xziptic & EZT_THOKMASK) { // Let's only spawn ONE of these per frame, thanks. @@ -810,7 +810,7 @@ void G_GhostTicker(void) 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)); + P_SetScale(mobj, g->mo->scale, true); if (type == MT_THOK) // spintrail-specific modification for MT_THOK { @@ -926,7 +926,7 @@ void G_GhostTicker(void) else follow->destscale = g->mo->destscale; if (follow->destscale != follow->scale) - P_SetScale(follow, follow->destscale); + P_SetScale(follow, follow->destscale, false); P_UnsetThingPosition(follow); temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); @@ -1079,7 +1079,7 @@ void G_ReadMetalTic(mobj_t *metal) { metal->destscale = READFIXED(metal_p); if (metal->destscale != metal->scale) - P_SetScale(metal, metal->destscale); + P_SetScale(metal, metal->destscale, false); } if (xziptic & EZT_THOKMASK) { // Let's only spawn ONE of these per frame, thanks. @@ -1117,7 +1117,7 @@ void G_ReadMetalTic(mobj_t *metal) mobj->angle = metal->angle; mobj->color = metal->color; mobj->skin = metal->skin; - P_SetScale(mobj, (mobj->destscale = metal->scale)); + P_SetScale(mobj, metal->scale, true); if (type == MT_THOK) // spintrail-specific modification for MT_THOK { @@ -1184,7 +1184,7 @@ void G_ReadMetalTic(mobj_t *metal) else follow->destscale = metal->destscale; if (follow->destscale != follow->scale) - P_SetScale(follow, follow->destscale); + P_SetScale(follow, follow->destscale, false); P_UnsetThingPosition(follow); temp = (metalversion < 0x000e) ? READINT16(metal_p)<<8 : READFIXED(metal_p); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 54c329373..952e7a690 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -925,13 +925,14 @@ static int lib_pSetScale(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); fixed_t newscale = luaL_checkfixed(L, 2); + boolean instant = lua_optboolean(L, 3); NOHUD INLEVEL if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); if (newscale < FRACUNIT/100) newscale = FRACUNIT/100; - P_SetScale(mobj, newscale); + P_SetScale(mobj, newscale, instant); return 0; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index b5c6c0329..ae1c72b14 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -732,7 +732,7 @@ static int mobj_set(lua_State *L) return luaL_error(L, "mobj.type %d out of range (0 - %d).", newtype, NUMMOBJTYPES-1); mo->type = newtype; mo->info = &mobjinfo[newtype]; - P_SetScale(mo, mo->scale); + P_SetScale(mo, mo->scale, false); break; } case mobj_info: @@ -806,9 +806,7 @@ static int mobj_set(lua_State *L) fixed_t scale = luaL_checkfixed(L, 3); if (scale < FRACUNIT/100) scale = FRACUNIT/100; - mo->destscale = scale; - P_SetScale(mo, scale); - mo->old_scale = scale; + P_SetScale(mo, scale, true); break; } case mobj_destscale: diff --git a/src/p_enemy.c b/src/p_enemy.c index 1073fd491..c801ee594 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1219,8 +1219,7 @@ static void P_FaceStabFlume(mobj_t *actor) if (P_MobjWasRemoved(flume)) return; - flume->destscale = actor->scale*3; - P_SetScale(flume, flume->destscale); + P_SetScale(flume, 3*actor->scale, true); P_SetTarget(&flume->target, actor); flume->sprite = SPR_JETF; flume->frame = FF_FULLBRIGHT; @@ -1337,8 +1336,7 @@ void A_FaceStabHurl(mobj_t *actor) { hwork = hwork->hnext; hwork->angle = actor->angle + ANGLE_90; - hwork->destscale = FixedSqrt(step*basesize); - P_SetScale(hwork, hwork->destscale); + P_SetScale(hwork, FixedSqrt(step*basesize), true); 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<destscale = FRACUNIT; dust->scalespeed = 4*FRACUNIT/TICRATE; dust->fuse = TICRATE; @@ -2523,7 +2521,7 @@ void A_VultureFly(mobj_t *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); if (!P_MobjWasRemoved(dust)) { - P_SetScale(dust, 2*FRACUNIT); + P_SetScale(dust, 2*FRACUNIT, true); dust->destscale = FRACUNIT/3; dust->scalespeed = FRACUNIT/40; dust->fuse = TICRATE*2; @@ -2732,15 +2730,9 @@ void A_LobShot(mobj_t *actor) return; if (actor->type == MT_BLACKEGGMAN) - { - shot->destscale = actor->scale/2; - P_SetScale(shot, actor->scale/2); - } + P_SetScale(shot, actor->scale/2, true); else - { - shot->destscale = actor->scale; - P_SetScale(shot, actor->scale); - } + P_SetScale(shot, actor->scale, true); P_SetTarget(&shot->target, actor); // where it came from @@ -3185,8 +3177,7 @@ void A_Boss1Laser(mobj_t *actor) if (!P_MobjWasRemoved(point)) { point->angle = actor->angle; - point->destscale = actor->scale; - P_SetScale(point, point->destscale); + P_SetScale(point, actor->scale, true); P_SetTarget(&point->target, actor); P_MobjCheckWater(point); if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) @@ -3197,7 +3188,8 @@ void A_Boss1Laser(mobj_t *actor) 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_SetScale(steam, size*actor->scale, false); + steam->old_scale = steam->scale; P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true); P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed()); if (point->info->painsound) @@ -3570,8 +3562,7 @@ void A_BossScream(mobj_t *actor) return; if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; - mo->destscale = actor->scale; - P_SetScale(mo, mo->destscale); + P_SetScale(mo, actor->scale, true); if (actor->info->deathsound) S_StartSound(mo, actor->info->deathsound); } @@ -4164,7 +4155,7 @@ static void P_DoBoss5Death(mobj_t *mo) MT_FSGNB); if (!P_MobjWasRemoved(pole)) { - P_SetScale(pole, (pole->destscale = 2*FRACUNIT)); + P_SetScale(pole, 2*FRACUNIT, true); pole->momx = P_ReturnThrustX(pole, pole->angle, speed); pole->momy = P_ReturnThrustY(pole, pole->angle, speed); P_SetTarget(&pole->tracer, P_SpawnMobj( @@ -4174,7 +4165,7 @@ static void P_DoBoss5Death(mobj_t *mo) if (!P_MobjWasRemoved(pole->tracer)) { pole->tracer->flags |= MF_NOCLIPTHING; - P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT)); + P_SetScale(pole->tracer, 2*FRACUNIT, true); pole->angle = pole->tracer->angle = mo->tracer->angle; pole->tracer->momx = pole->momx; pole->tracer->momy = pole->momy; @@ -4713,10 +4704,7 @@ void A_BubbleSpawn(mobj_t *actor) bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_MEDIUMBUBBLE); if (bubble) - { - bubble->destscale = actor->scale; - P_SetScale(bubble, actor->scale); - } + P_SetScale(bubble, actor->scale, true); } // Function: A_FanBubbleSpawn @@ -4759,10 +4747,7 @@ void A_FanBubbleSpawn(mobj_t *actor) bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_MEDIUMBUBBLE); if (bubble) - { - bubble->destscale = actor->scale; - P_SetScale(bubble, actor->scale); - } + P_SetScale(bubble, actor->scale, true); } // Function: A_BubbleRise @@ -5039,8 +5024,7 @@ void A_ThrownRing(mobj_t *actor) P_SetTarget(&ring->target, actor); ring->color = actor->color; //copy color */ - ring->destscale = actor->scale; - P_SetScale(ring, actor->scale); + P_SetScale(ring, actor->scale, true); } } @@ -5619,8 +5603,7 @@ void A_JetbThink(mobj_t *actor) if (!P_MobjWasRemoved(bomb)) { P_SetTarget(&bomb->target, actor); - bomb->destscale = actor->scale; - P_SetScale(bomb, actor->scale); + P_SetScale(bomb, actor->scale, true); actor->reactiontime = TICRATE; // one second S_StartSound(actor, actor->info->attacksound); } @@ -5794,7 +5777,8 @@ void A_MinusDigging(mobj_t *actor) if (P_MobjWasRemoved(par)) return; P_SetMobjState(par, actor->info->raisestate); - P_SetScale(par, actor->scale*2); + P_SetScale(par, 2*actor->scale, false); + par->old_scale = par->scale; if (actor->eflags & MFE_VERTICALFLIP) par->eflags |= MFE_VERTICALFLIP; return; @@ -5867,7 +5851,8 @@ void A_MinusPopup(mobj_t *actor) continue; P_Thrust(rock, ani*i, FRACUNIT); P_SetObjectMomZ(rock, 3*FRACUNIT, false); - P_SetScale(rock, rock->scale/3); + P_SetScale(rock, rock->scale/3, false); + rock->old_scale = rock->scale; } P_RadiusAttack(actor, actor, 2*actor->radius, 0, true); if (actor->tracer) @@ -5906,7 +5891,8 @@ void A_MinusCheck(mobj_t *actor) continue; P_Thrust(rock, ani*i, FRACUNIT); P_SetObjectMomZ(rock, 3*FRACUNIT, false); - P_SetScale(rock, rock->scale/3); + P_SetScale(rock, rock->scale/3, false); + rock->old_scale = rock->scale; } } } @@ -8227,8 +8213,9 @@ void A_EggShield(mobj_t *actor) else actor->z = actor->target->z; + P_SetScale(actor, actor->target->scale, false); actor->destscale = actor->target->destscale; - P_SetScale(actor, actor->target->scale); + actor->old_scale = actor->target->old_scale; actor->floorz = actor->target->floorz; actor->ceilingz = actor->target->ceilingz; @@ -8509,7 +8496,7 @@ void A_Boss3ShockThink(mobj_t *actor) P_SetTarget(&snew->target, actor->target); snew->fuse = actor->fuse; - P_SetScale(snew, actor->scale); + P_SetScale(snew, actor->scale, true); snew->destscale = actor->destscale; snew->scalespeed = actor->scalespeed; @@ -8708,8 +8695,7 @@ void A_SmokeTrailer(mobj_t *actor) if (P_MobjWasRemoved(th)) return; P_SetObjectMomZ(th, FRACUNIT, false); - th->destscale = actor->scale; - P_SetScale(th, actor->scale); + P_SetScale(th, actor->scale, true); th->tics -= P_RandomByte() & 3; if (th->tics < 1) th->tics = 1; @@ -9453,8 +9439,7 @@ void A_BossJetFume(mobj_t *actor) if (!P_MobjWasRemoved(filler)) { P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); + P_SetScale(filler, actor->scale, true); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; filler->fuse = 56; @@ -9471,8 +9456,7 @@ void A_BossJetFume(mobj_t *actor) if (!P_MobjWasRemoved(filler)) { P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); + P_SetScale(filler, actor->scale, true); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; filler->fuse = 57; @@ -9485,7 +9469,7 @@ void A_BossJetFume(mobj_t *actor) { P_SetTarget(&filler->target, actor); filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); + P_SetScale(filler, actor->scale, true); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; filler->fuse = 58; @@ -9506,8 +9490,7 @@ void A_BossJetFume(mobj_t *actor) filler = P_SpawnMobj(jetx, jety, jetz, MT_PROPELLER); P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); + P_SetScale(filler, actor->scale, true); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; filler->angle = actor->angle - ANGLE_180; @@ -9522,7 +9505,7 @@ void A_BossJetFume(mobj_t *actor) P_SetTarget(&filler->target, actor); filler->fuse = 59; P_SetTarget(&actor->tracer, filler); - P_SetScale(filler, (filler->destscale = actor->scale/3)); + P_SetScale(filler, actor->scale/3, true); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; filler->color = SKINCOLOR_ICY; @@ -9541,8 +9524,7 @@ void A_BossJetFume(mobj_t *actor) { P_SetTarget(&filler->target, actor); // Boss 4 already uses its tracer for other things - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); + P_SetScale(filler, actor->scale, true); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; } @@ -9564,8 +9546,7 @@ void A_BossJetFume(mobj_t *actor) { filler->movefactor = movefactor; P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); + P_SetScale(filler, actor->scale, true); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; } @@ -9811,12 +9792,13 @@ void A_ToggleFlameJet(mobj_t* actor) // var1 = Angle adjustment (aka orbit speed) // var2: // Bits 1-10: height offset, max 1023 -// Bits 11-16: X radius factor (max 63, default 20) +// Bits 11-16: X radius factor (max 63, default 32) // Bit 17: set if object is Nightopian Helper // Bit 18: set to define X/Y/Z rotation factor -// Bits 19-20: Unused +// Bit 19: set to not sync scale to player +// Bit 20: Unused // Bits 21-26: Y radius factor (max 63, default 32) -// Bits 27-32: Z radius factor (max 63, default 32) +// Bits 27-32: Z radius factor (max 63, default 20) // // If MF_GRENADEBOUNCE is flagged on mobj, use actor->threshold to define X/Y/Z radius factor, max 1023 each: // Bits 1-10: X factor @@ -9857,6 +9839,12 @@ void A_OrbitNights(mobj_t* actor) } else { + if (!donotrescale) + { + P_SetScale(actor, actor->target->scale, true); + actor->old_scale = actor->target->old_scale; + } + actor->extravalue1 += var1; P_UnsetThingPosition(actor); { @@ -9884,9 +9872,6 @@ void A_OrbitNights(mobj_t* actor) else actor->flags2 &= ~MF2_DONTDRAW; } - - if (!donotrescale && actor->destscale != actor->target->destscale) - actor->destscale = actor->target->destscale; } } @@ -11135,9 +11120,10 @@ void A_SetScale(mobj_t *actor) return; } - target->destscale = locvar1; // destination scale - if (!(locvar2 & 65535)) - P_SetScale(target, locvar1); // this instantly changes current scale to var1 if used, if not destscale will alter scale to var1 anyway + if ((locvar2 & 65535) == 0) + P_SetScale(target, locvar1, true); // this instantly changes current scale to var1 if used, if not destscale will alter scale to var1 over time + else + target->destscale = locvar1; // destination scale } // Function: A_RemoteDamage @@ -11281,8 +11267,7 @@ void A_TrapShot(mobj_t *actor) if (actor->eflags & MFE_VERTICALFLIP) missile->flags2 |= MF2_OBJECTFLIP; - missile->destscale = actor->scale; - P_SetScale(missile, actor->scale); + P_SetScale(missile, actor->scale, true); if (missile->info->seesound) S_StartSound(missile, missile->info->seesound); @@ -11356,8 +11341,7 @@ void A_VileTarget(mobj_t *actor) fog->eflags |= MFE_VERTICALFLIP; fog->flags2 |= MF2_OBJECTFLIP; } - fog->destscale = actor->target->scale; - P_SetScale(fog, fog->destscale); + P_SetScale(fog, actor->target->scale, true); P_SetTarget(&actor->tracer, fog); P_SetTarget(&fog->target, actor); @@ -11390,8 +11374,7 @@ void A_VileTarget(mobj_t *actor) fog->eflags |= MFE_VERTICALFLIP; fog->flags2 |= MF2_OBJECTFLIP; } - fog->destscale = players[i].mo->scale; - P_SetScale(fog, fog->destscale); + P_SetScale(fog, players[i].mo->scale, true); 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); @@ -11548,8 +11531,8 @@ void A_VileFire(mobj_t *actor) return; // keep to same scale and gravity as tracer ALWAYS - actor->destscale = dest->scale; - P_SetScale(actor, actor->destscale); + P_SetScale(actor, dest->scale, true); + actor->old_scale = dest->old_scale; if (dest->eflags & MFE_VERTICALFLIP) { actor->eflags |= MFE_VERTICALFLIP; @@ -12729,8 +12712,7 @@ void A_LightBeamReset(mobj_t *actor) if (LUA_CallAction(A_LIGHTBEAMRESET, actor)) return; - actor->destscale = FRACUNIT + P_SignedRandom()*FRACUNIT/256; - P_SetScale(actor, actor->destscale); + P_SetScale(actor, FRACUNIT + P_SignedRandom()*FRACUNIT/256, true); if (!actor->spawnpoint) return; // this can't work properly welp @@ -13315,7 +13297,7 @@ void A_DoNPCSkid(mobj_t *actor) { particle->tics = 10; - P_SetScale(particle, 2*actor->scale/3); + P_SetScale(particle, 2*actor->scale/3, true); particle->destscale = actor->scale; P_SetObjectMomZ(particle, FRACUNIT, false); } @@ -13738,7 +13720,7 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi continue; dust->angle = ang*i + ANGLE_90; - P_SetScale(dust, FixedMul(initscale, scale)); + P_SetScale(dust, FixedMul(initscale, scale), true); dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale); dust->scalespeed = scale/24; P_Thrust(dust, ang*i, speed + FixedMul(P_RandomFixed(), scale)); @@ -13877,7 +13859,8 @@ void A_DustDevilThink(mobj_t *actor) while (layer && !P_MobjWasRemoved(layer)) { angle_t fa = layer->angle >> ANGLETOFINESHIFT; P_MoveOrigin(layer, layer->x + 5 * FixedMul(scale, FINECOSINE(fa)), layer->y + 5 * FixedMul(scale, FINESINE(fa)), layer->z); - layer->scale = scale; + P_SetScale(layer, scale, true); + layer->old_scale = actor->old_scale; layer->angle += ANG10 / 2; layer->momx = actor->momx; layer->momy = actor->momy; @@ -13891,8 +13874,7 @@ void A_DustDevilThink(mobj_t *actor) if (!P_MobjWasRemoved(dust)) { P_SetMobjState(dust, dust->info->spawnstate + P_RandomRange(0, 2)); - dust->destscale = scale * 3; - P_SetScale(dust, dust->destscale); + P_SetScale(dust, 3 * scale, true); } } @@ -13911,6 +13893,7 @@ void A_DustDevilThink(mobj_t *actor) layer = P_SpawnMobj(px, py, pz, MT_DUSTLAYER); if (P_MobjWasRemoved(layer)) continue; + P_SetScale(layer, scale, true); layer->momz = 5 * scale; layer->angle = ANGLE_90 + ANGLE_90*i; layer->extravalue1 = TICRATE * 3; @@ -14530,8 +14513,7 @@ void A_MinecartSparkThink(mobj_t *actor) continue; trail->tics = 2; trail->sprite = actor->sprite; - P_SetScale(trail, trail->scale/4); - trail->destscale = trail->scale; + P_SetScale(trail, trail->scale/4, true); } } @@ -14654,8 +14636,16 @@ void A_FireShrink(mobj_t *actor) if (LUA_CallAction(A_FIRESHRINK, actor)) return; - actor->destscale = locvar1; - actor->scalespeed = FRACUNIT/locvar2; + if (locvar2 == 0) + { + P_SetScale(actor, locvar1, true); + actor->scalespeed = FRACUNIT/12; // Reset scalespeed to the default + } + else + { + actor->destscale = locvar1; + actor->scalespeed = FRACUNIT/locvar2; + } } // Function: A_SpawnPterabytes diff --git a/src/p_inter.c b/src/p_inter.c index d8765e7a2..74852183e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2765,8 +2765,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget 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_SetScale(mo, target->scale, true); P_SetMobjState(mo, mo->info->raisestate); break; @@ -3957,8 +3956,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) mo->fuse = 8*TICRATE; P_SetTarget(&mo->target, player->mo); - mo->destscale = player->mo->scale; - P_SetScale(mo, player->mo->scale); + P_SetScale(mo, player->mo->scale, true); // Angle offset by player angle, then slightly offset by amount of rings fa = ((i*FINEANGLES/16) + va - ((num_rings-1)*FINEANGLES/32)) & FINEMASK; @@ -4094,8 +4092,7 @@ void P_PlayerWeaponPanelBurst(player_t *player) 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); + P_SetScale(mo, player->mo->scale, true); // Angle offset by player angle fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; @@ -4183,8 +4180,7 @@ void P_PlayerWeaponAmmoBurst(player_t *player) player->powers[power] = 0; mo->fuse = 12*TICRATE; - mo->destscale = player->mo->scale; - P_SetScale(mo, player->mo->scale); + P_SetScale(mo, player->mo->scale, true); // Angle offset by player angle fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; @@ -4231,8 +4227,7 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) 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); \ + P_SetScale(mo, player->mo->scale, true); \ mo->momx = FixedMul(FINECOSINE(fa),ns); \ if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ mo->momy = FixedMul(FINESINE(fa),ns); \ @@ -4254,8 +4249,7 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) 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); \ + P_SetScale(mo, player->mo->scale, true); \ mo->momx = FixedMul(FINECOSINE(fa),ns); \ if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ mo->momy = FixedMul(FINESINE(fa),ns); \ diff --git a/src/p_mobj.c b/src/p_mobj.c index f16fef2f0..06287091a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -917,7 +917,7 @@ void P_ExplodeMissile(mobj_t *mo) explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); if (!P_MobjWasRemoved(explodemo)) { - P_SetScale(explodemo, mo->scale); + P_SetScale(explodemo, mo->scale, true); explodemo->destscale = mo->destscale; explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); @@ -926,7 +926,7 @@ void P_ExplodeMissile(mobj_t *mo) explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); if (!P_MobjWasRemoved(explodemo)) { - P_SetScale(explodemo, mo->scale); + P_SetScale(explodemo, mo->scale, true); explodemo->destscale = mo->destscale; explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); @@ -935,7 +935,7 @@ void P_ExplodeMissile(mobj_t *mo) explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); if (!P_MobjWasRemoved(explodemo)) { - P_SetScale(explodemo, mo->scale); + P_SetScale(explodemo, mo->scale, true); explodemo->destscale = mo->destscale; explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); @@ -944,7 +944,7 @@ void P_ExplodeMissile(mobj_t *mo) explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); if (!P_MobjWasRemoved(explodemo)) { - P_SetScale(explodemo, mo->scale); + P_SetScale(explodemo, mo->scale, true); explodemo->destscale = mo->destscale; explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); @@ -3108,8 +3108,7 @@ boolean P_SceneryZMovement(mobj_t *mo) 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; - P_SetScale(explodemo, mo->scale); + P_SetScale(explodemo, mo->scale, true); } if (mo->threshold != 42) // Don't make pop sound if threshold is 42. @@ -3135,7 +3134,7 @@ boolean P_SceneryZMovement(mobj_t *mo) mobj_t *flower = P_SpawnMobjFromMobj(mo, 0, 0, 0, flowertype); if (flower) { - P_SetScale(flower, mo->scale/16); + P_SetScale(flower, mo->scale/16, true); flower->destscale = mo->scale; flower->scalespeed = mo->scale/8; } @@ -3375,10 +3374,7 @@ void P_MobjCheckWater(mobj_t *mobj) else splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); if (!P_MobjWasRemoved(splish)) - { - splish->destscale = mobj->scale; - P_SetScale(splish, mobj->scale); - } + P_SetScale(splish, mobj->scale, true); } // skipping stone! @@ -3417,10 +3413,7 @@ void P_MobjCheckWater(mobj_t *mobj) else splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); if (!P_MobjWasRemoved(splish)) - { - splish->destscale = mobj->scale; - P_SetScale(splish, mobj->scale); - } + P_SetScale(splish, mobj->scale, true); } } @@ -3471,8 +3464,7 @@ void P_MobjCheckWater(mobj_t *mobj) else bubble->momz = 0; - bubble->destscale = mobj->scale; - P_SetScale(bubble, mobj->scale); + P_SetScale(bubble, mobj->scale, true); } } } @@ -5136,8 +5128,7 @@ static void P_Boss7Thinker(mobj_t *mobj) mobj_t *smoke = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height, MT_SMOKE); if (!P_MobjWasRemoved(smoke)) { - smoke->destscale = mobj->destscale; - P_SetScale(smoke, smoke->destscale); + P_SetScale(smoke, mobj->destscale, true); smoke->momz = FixedMul(FRACUNIT, smoke->scale); } } @@ -5586,7 +5577,7 @@ static void P_Boss9Thinker(mobj_t *mobj) if (mobj->hprev) { mobj->hprev->destscale = FRACUNIT + (2*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2); - P_SetScale(mobj->hprev, mobj->hprev->destscale); + P_SetScale(mobj->hprev, mobj->hprev->destscale, false); P_MoveOrigin(mobj->hprev, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->hprev->height/2); mobj->hprev->momx = mobj->momx; @@ -5612,8 +5603,8 @@ static void P_Boss9Thinker(mobj_t *mobj) { S_StopSound(missile); if (mobj->extravalue1 >= 2) - P_SetScale(missile, FRACUNIT>>1); - missile->destscale = missile->scale>>1; + P_SetScale(missile, FRACUNIT/2, true); + missile->destscale = missile->scale/2; missile->fuse = TICRATE/2; missile->scalespeed = abs(missile->destscale - missile->scale)/missile->fuse; missile->z -= missile->height/2; @@ -5636,7 +5627,7 @@ static void P_Boss9Thinker(mobj_t *mobj) 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); + P_SetScale(spread, missile->scale, true); spread->destscale = missile->destscale; spread->scalespeed = missile->scalespeed; spread->fuse = missile->fuse; @@ -5660,7 +5651,7 @@ static void P_Boss9Thinker(mobj_t *mobj) spread = P_SpawnMissile(mobj, mobj->target, missile->type); if (P_MobjWasRemoved(spread)) continue; - P_SetScale(spread, missile->scale); + P_SetScale(spread, missile->scale, true); spread->destscale = missile->destscale; spread->fuse = missile->fuse; spread->z -= spread->height/2; @@ -5717,12 +5708,12 @@ static void P_Boss9Thinker(mobj_t *mobj) { if (mobj->health > mobj->info->damage) { - P_SetScale(missile, FRACUNIT/3); + P_SetScale(missile, FRACUNIT/3, true); missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power } else { - P_SetScale(missile, FRACUNIT/5); + P_SetScale(missile, FRACUNIT/5, true); missile->color = SKINCOLOR_SUNSET; // sonic cd electric power } missile->destscale = missile->scale*2; @@ -5785,10 +5776,7 @@ static void P_Boss9Thinker(mobj_t *mobj) if (!P_MobjWasRemoved(missile)) { if (mobj->extravalue1 >= 2) - { - missile->destscale = FRACUNIT>>1; - P_SetScale(missile, missile->destscale); - } + P_SetScale(missile, FRACUNIT/2, true); missile->fuse = 3*TICRATE; missile->z -= missile->height/2; @@ -5807,8 +5795,7 @@ static void P_Boss9Thinker(mobj_t *mobj) 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); + P_SetScale(spread, FRACUNIT/2, true); spread->fuse = missile->fuse; } P_InstaThrust(missile,missile->angle,missile->info->speed); @@ -5825,8 +5812,7 @@ static void P_Boss9Thinker(mobj_t *mobj) spread = P_SpawnMissile(mobj, mobj->target, missile->type); if (!P_MobjWasRemoved(spread)) { - spread->destscale = FRACUNIT>>1; - P_SetScale(spread, spread->destscale); + P_SetScale(spread, FRACUNIT/2, true); spread->fuse = missile->fuse; spread->z -= spread->height/2; } @@ -6086,8 +6072,12 @@ static void P_Boss9Thinker(mobj_t *mobj) whoosh->flags |= MF_NOCLIPHEIGHT; #endif - P_SetMobjState(mobj->tracer, S_JETFUMEFLASH); - P_SetScale(mobj->tracer, mobj->scale << 1); + if (!P_MobjWasRemoved(mobj->tracer)) + { + P_SetMobjState(mobj->tracer, S_JETFUMEFLASH); + P_SetScale(mobj->tracer, 2*mobj->scale, false); + mobj->tracer->old_scale = mobj->tracer->scale; + } } else { @@ -6422,28 +6412,24 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb // // Sets the sprite scaling // -void P_SetScale(mobj_t *mobj, fixed_t newscale) +void P_SetScale(mobj_t *mobj, fixed_t newscale, boolean instant) { - player_t *player; - fixed_t oldscale; - if (!mobj) return; - oldscale = mobj->scale; //keep for adjusting stuff below - - mobj->scale = newscale; - - mobj->radius = FixedMul(FixedDiv(mobj->radius, oldscale), newscale); - mobj->height = FixedMul(FixedDiv(mobj->height, oldscale), newscale); - - player = mobj->player; - - if (player) + if (mobj->player) { G_GhostAddScale(newscale); - player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it! + // Nonono don't calculate viewheight elsewhere, this is the best place for it! + mobj->player->viewheight = FixedMul(FixedDiv(mobj->player->viewheight, mobj->scale), newscale); } + + mobj->radius = FixedMul(FixedDiv(mobj->radius, mobj->scale), newscale); + mobj->height = FixedMul(FixedDiv(mobj->height, mobj->scale), newscale); + + mobj->scale = newscale; + if (instant) + mobj->destscale = mobj->old_scale = newscale; } void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on your target @@ -6798,8 +6784,7 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) thing->flags |= MF_NOCLIPHEIGHT; thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP); - P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale)); - thing->destscale = thing->scale; + P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale), true); thing->old_scale = FixedMul(thing->target->old_scale, thing->target->player->shieldscale); #define NewMH(mobj) mobj->height // Ugly mobj-height and player-height defines, for the sake of prettier code @@ -7147,11 +7132,11 @@ static void P_MobjScaleThink(mobj_t *mobj) correctionType = 2; // Correct Z position by moving down if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) - P_SetScale(mobj, mobj->destscale); + P_SetScale(mobj, mobj->destscale, false); else if (mobj->scale < mobj->destscale) - P_SetScale(mobj, mobj->scale + mobj->scalespeed); + P_SetScale(mobj, mobj->scale + mobj->scalespeed, false); else if (mobj->scale > mobj->destscale) - P_SetScale(mobj, mobj->scale - mobj->scalespeed); + P_SetScale(mobj, mobj->scale - mobj->scalespeed, false); if (correctionType == 1) mobj->z -= (mobj->height - oldheight)/2; @@ -7244,8 +7229,9 @@ static boolean P_DrownNumbersSceneryThink(mobj_t *mobj) mobj->x = mobj->target->x; mobj->y = mobj->target->y; + P_SetScale(mobj, mobj->target->scale, false); mobj->destscale = mobj->target->destscale; - P_SetScale(mobj, mobj->target->scale); + mobj->old_scale = mobj->target->old_scale; if (mobj->target->eflags & MFE_VERTICALFLIP) { @@ -7406,10 +7392,10 @@ static boolean P_ParticleGenSceneryThink(mobj_t *mobj) (mobjtype_t)mobj->threshold); if (!P_MobjWasRemoved(spawn)) { - P_SetScale(spawn, mobj->scale); - spawn->momz = FixedMul(mobj->movefactor, spawn->scale); + P_SetScale(spawn, mobj->scale, true); spawn->destscale = spawn->scale/100; spawn->scalespeed = spawn->scale/mobj->health; + spawn->momz = FixedMul(mobj->movefactor, spawn->scale); 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 @@ -7627,8 +7613,7 @@ static void P_RosySceneryThink(mobj_t *mobj) mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT); if (!P_MobjWasRemoved(cdlhrt)) { - cdlhrt->destscale = (5*mobj->scale) >> 4; - P_SetScale(cdlhrt, cdlhrt->destscale); + P_SetScale(cdlhrt, (5*mobj->scale) >> 4, true); cdlhrt->fuse = (5*TICRATE) >> 1; cdlhrt->momz = mobj->scale; P_SetTarget(&cdlhrt->target, mobj); @@ -7882,8 +7867,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP); + P_SetScale(mobj, mobj->target->scale, false); mobj->destscale = mobj->target->destscale; - P_SetScale(mobj, mobj->target->scale); + mobj->old_scale = mobj->target->old_scale; if (!(mobj->eflags & MFE_VERTICALFLIP)) mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale); @@ -8033,7 +8019,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) } P_SetThingPosition(mobj); - P_SetScale(mobj, mobj->target->scale); + P_SetScale(mobj, mobj->target->scale, false); + mobj->destscale = mobj->target->destscale; + mobj->old_scale = mobj->target->old_scale; } break; case MT_TUTORIALFLOWER: @@ -8474,8 +8462,8 @@ static void P_ArrowThink(mobj_t *mobj) if (!P_MobjWasRemoved(dust)) { dust->tics = 18; - dust->scalespeed = 4096; dust->destscale = FRACUNIT/32; + dust->scalespeed = FRACUNIT/16; } } } @@ -9887,9 +9875,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) traindust->frame = P_RandomRange(0, 8)|FF_TRANS90; traindust->angle = mobj->angle; traindust->tics = TICRATE*4; + P_SetScale(traindust, FRACUNIT*6, true); traindust->destscale = FRACUNIT*64; traindust->scalespeed = FRACUNIT/24; - P_SetScale(traindust, FRACUNIT*6); } break; case MT_TRAINSTEAMSPAWNER: @@ -9900,9 +9888,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_SetMobjState(steam, S_TRAINSTEAM); steam->frame = P_RandomRange(0, 1)|FF_TRANS90; steam->tics = TICRATE*8; + P_SetScale(steam, FRACUNIT*16, true); steam->destscale = FRACUNIT*64; steam->scalespeed = FRACUNIT/8; - P_SetScale(steam, FRACUNIT*16); steam->momx = P_SignedRandom()*32; steam->momy = -64*FRACUNIT; steam->momz = 2*FRACUNIT; @@ -10891,7 +10879,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) if (titlemapinaction) mobj->flags &= ~MF_NOTHINK; break; case MT_LOCKONINF: - P_SetScale(mobj, (mobj->destscale = 3*mobj->scale)); + P_SetScale(mobj, 3*mobj->scale, true); break; case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: mobj->fuse = mobj->info->painchance; @@ -10902,8 +10890,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) if (P_MobjWasRemoved(spawn)) break; - spawn->destscale = mobj->scale; - P_SetScale(spawn, mobj->scale); + P_SetScale(spawn, mobj->scale, true); P_SetTarget(&spawn->target, mobj); } break; @@ -10920,8 +10907,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) if (P_MobjWasRemoved(spawn)) break; - spawn->destscale = mobj->scale; - P_SetScale(spawn, mobj->scale); + P_SetScale(spawn, mobj->scale, true); P_SetTarget(&mobj->tracer, spawn); P_SetTarget(&spawn->target, mobj); } @@ -10938,8 +10924,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) if (P_MobjWasRemoved(ball)) continue; - ball->destscale = mobj->scale; - P_SetScale(ball, mobj->scale); + P_SetScale(ball, mobj->scale, true); P_SetTarget(&ball->target, mobj); ball->movedir = FixedAngle(FixedMul(FixedDiv(i<info->damage<threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale); @@ -10960,8 +10945,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) if (P_MobjWasRemoved(ball)) continue; - ball->destscale = mobj->scale; - P_SetScale(ball, mobj->scale); + P_SetScale(ball, mobj->scale, true); P_SetTarget(&lastball->tracer, ball); P_SetTarget(&ball->target, mobj); lastball = ball; @@ -11821,7 +11805,7 @@ void P_SpawnPlayer(INT32 playernum) p->awayviewtics = 0; // set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't. - P_SetScale(mobj, mobj->destscale); + P_SetScale(mobj, mobj->destscale, true); P_FlashPal(p, 0, 0); // Resets // Set bounds accurately. @@ -11995,7 +11979,7 @@ void P_MovePlayerToStarpost(INT32 playernum) z = p->starpostz << FRACBITS; - P_SetScale(mobj, (mobj->destscale = abs(p->starpostscale))); + P_SetScale(mobj, abs(p->starpostscale), true); if (p->starpostscale < 0) { @@ -13103,8 +13087,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (P_MobjWasRemoved(corona)) break; - P_SetScale(corona, (corona->destscale = mobj->scale*3)); P_SetTarget(&mobj->tracer, corona); + P_SetScale(corona, 3*mobj->scale, true); } break; case MT_FLAMEHOLDER: @@ -13122,8 +13106,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (P_MobjWasRemoved(corona)) break; - P_SetScale(corona, (corona->destscale = flame->scale*3)); P_SetTarget(&flame->tracer, corona); + P_SetScale(corona, 3*flame->scale, true); } } break; @@ -13211,10 +13195,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_DSZSTALAGMITE: case MT_DSZ2STALAGMITE: case MT_KELP: - if (mthing->args[0]) { // make mobj twice as big as normal - P_SetScale(mobj, 2*mobj->scale); // not 2*FRACUNIT in case of something like the old ERZ3 mode - mobj->destscale = mobj->scale; - } + if (mthing->args[0]) // make mobj twice as big as normal + P_SetScale(mobj, 2*mobj->scale, true); // not 2*FRACUNIT in case of something like the old ERZ3 mode break; case MT_THZTREE: { // Spawn the branches @@ -13293,10 +13275,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_LAVAFALL: mobj->fuse = 30 + mthing->args[0]; if (mthing->args[1]) - { - P_SetScale(mobj, 2*mobj->scale); - mobj->destscale = mobj->scale; - } + P_SetScale(mobj, 2*mobj->scale, true); break; case MT_PYREFLY: //start on fire if args[0], otherwise behave normally @@ -13359,8 +13338,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; P_SetTarget(&elecmobj->target, mobj); elecmobj->angle = FixedAngle(mthing->angle << FRACBITS); - elecmobj->destscale = mobj->scale*2; - P_SetScale(elecmobj, elecmobj->destscale); + P_SetScale(elecmobj, 2*mobj->scale, true); } break; case MT_STARPOST: @@ -13418,8 +13396,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean return false; } base->angle = mobjangle + ANGLE_90; + P_SetScale(base, mobj->scale, true); base->destscale = mobj->destscale; - P_SetScale(base, mobj->scale); P_SetTarget(&base->target, mobj); P_SetTarget(&mobj->tracer, base); } @@ -13596,8 +13574,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, return NULL; mobj->spawnpoint = mthing; - P_SetScale(mobj, FixedMul(mobj->scale, mthing->scale)); + P_SetScale(mobj, FixedMul(mobj->scale, mthing->scale), false); mobj->destscale = FixedMul(mobj->destscale, mthing->scale); + mobj->old_scale = FixedMul(mobj->old_scale, mthing->scale); mobj->spritexscale = mthing->spritexscale; mobj->spriteyscale = mthing->spriteyscale; @@ -14050,8 +14029,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; - th->destscale = source->scale; - P_SetScale(th, source->scale); + P_SetScale(th, source->scale, true); speed = FixedMul(th->info->speed, th->scale); @@ -14114,8 +14092,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; - th->destscale = source->scale; - P_SetScale(th, source->scale); + P_SetScale(th, source->scale, true); speed = FixedMul(th->info->speed, th->scale); @@ -14181,8 +14158,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; - th->destscale = source->scale; - P_SetScale(th, source->scale); + P_SetScale(th, source->scale, true); speed = FixedMul(th->info->speed, th->scale); @@ -14253,8 +14229,7 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type) if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; - th->destscale = source->scale; - P_SetScale(th, source->scale); + P_SetScale(th, source->scale, true); if (source->type == MT_METALSONIC_BATTLE && source->health < 4) speed = FixedMul(FixedMul(th->info->speed, 3*FRACUNIT/2), th->scale); @@ -14356,8 +14331,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai if (source->eflags & MFE_VERTICALFLIP) th->flags2 |= MF2_OBJECTFLIP; - th->destscale = source->scale; - P_SetScale(th, source->scale); + P_SetScale(th, source->scale, true); th->flags2 |= flags2; @@ -14439,8 +14413,8 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo newmobj->old_z2 = mobj->old_z2 + zofs; } + P_SetScale(newmobj, mobj->scale, false); newmobj->destscale = mobj->destscale; - P_SetScale(newmobj, mobj->scale); newmobj->old_x2 = mobj->old_x2 + xofs; newmobj->old_y2 = mobj->old_y2 + yofs; diff --git a/src/p_mobj.h b/src/p_mobj.h index a980691be..bc6601ea3 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -510,7 +510,7 @@ void P_SnowThinker(precipmobj_t *mobj); void P_RainThinker(precipmobj_t *mobj); void P_NullPrecipThinker(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj); -void P_SetScale(mobj_t *mobj, fixed_t newscale); +void P_SetScale(mobj_t *mobj, fixed_t newscale, boolean instant); void P_XYMovement(mobj_t *mo); void P_RingXYMovement(mobj_t *mo); void P_SceneryXYMovement(mobj_t *mo); diff --git a/src/p_user.c b/src/p_user.c index e6165c2a3..0037845c0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2037,8 +2037,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) P_SetTarget(&ghost->target, mobj); P_SetTarget(&ghost->dontdrawforviewmobj, mobj); // Hide the ghost in first-person - P_SetScale(ghost, mobj->scale); - ghost->destscale = mobj->scale; + P_SetScale(ghost, mobj->scale, true); if (mobj->eflags & MFE_VERTICALFLIP) { @@ -2096,6 +2095,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->old_pitch = mobj->old_pitch2; ghost->old_roll = mobj->old_roll2; ghost->old_spriteroll = mobj->old_spriteroll2; + ghost->old_scale = mobj->old_scale2; return ghost; } @@ -2151,7 +2151,7 @@ void P_SpawnThokMobj(player_t *player) mobj->eflags |= (player->mo->eflags & MFE_VERTICALFLIP); // scale - P_SetScale(mobj, (mobj->destscale = player->mo->scale)); + P_SetScale(mobj, player->mo->scale, true); if (type == MT_THOK) // spintrail-specific modification for MT_THOK { @@ -2215,8 +2215,7 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type) mobj->eflags |= (player->mo->eflags & MFE_VERTICALFLIP); // scale - P_SetScale(mobj, player->mo->scale); - mobj->destscale = player->mo->scale; + P_SetScale(mobj, player->mo->scale, true); if (type == MT_THOK) // spintrail-specific modification for MT_THOK { @@ -3035,9 +3034,8 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft); P_SetTarget(&numbermobj->target, player->mo); + P_SetScale(numbermobj, player->mo->scale, true); numbermobj->threshold = 40; - numbermobj->destscale = player->mo->scale; - P_SetScale(numbermobj, player->mo->scale); } } } @@ -3099,10 +3097,7 @@ static void P_CheckInvincibilityTimer(player_t *player) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); if (!P_MobjWasRemoved(sparkle)) - { - sparkle->destscale = player->mo->scale; - P_SetScale(sparkle, player->mo->scale); - } + P_SetScale(sparkle, player->mo->scale, true); } // Resume normal music stuff. @@ -3177,8 +3172,7 @@ static void P_DoBubbleBreath(player_t *player) if (bubble) { bubble->threshold = 42; - bubble->destscale = player->mo->scale; - P_SetScale(bubble, bubble->destscale); + P_SetScale(bubble, player->mo->scale, true); } // Tails stirs up the water while flying in it @@ -3200,20 +3194,14 @@ static void P_DoBubbleBreath(player_t *player) player->mo->y + stirwatery, stirwaterz, MT_SMALLBUBBLE); if (!P_MobjWasRemoved(bubble)) - { - bubble->destscale = player->mo->scale; - P_SetScale(bubble,bubble->destscale); - } + P_SetScale(bubble, player->mo->scale, true); bubble = P_SpawnMobj( player->mo->x - stirwaterx, player->mo->y - stirwatery, stirwaterz, MT_SMALLBUBBLE); if (!P_MobjWasRemoved(bubble)) - { - bubble->destscale = player->mo->scale; - P_SetScale(bubble,bubble->destscale); - } + P_SetScale(bubble, player->mo->scale, true); } } @@ -4421,10 +4409,7 @@ static void P_DoSuperStuff(player_t *player) { spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); if (!P_MobjWasRemoved(spark)) - { - spark->destscale = player->mo->scale; - P_SetScale(spark, player->mo->scale); - } + P_SetScale(spark, player->mo->scale, true); } // Ran out of rings while super! @@ -4674,8 +4659,7 @@ void P_DoSpinDashDust(player_t *player) P_SetMobjState(particle, S_SPINDUST_FIRE1); P_SetTarget(&particle->target, player->mo); - particle->destscale = (2*player->mo->scale)/3; - P_SetScale(particle, particle->destscale); + P_SetScale(particle, (2*player->mo->scale)/3, true); if (player->mo->eflags & MFE_VERTICALFLIP) // readjust z position if needed particle->z = player->mo->z + player->mo->height - particle->height; prandom[0] = P_RandomFixed()<<2; // P_RandomByte()<<10 @@ -5074,7 +5058,7 @@ void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type) if (!P_MobjWasRemoved(missile)) { P_SetTarget(&missile->target, player->mo); - P_SetScale(missile, (missile->destscale >>= 1)); + P_SetScale(missile, missile->destscale/2, true); missile->angle = ang + movang; missile->fuse = TICRATE/2; missile->extravalue2 = (99*FRACUNIT)/100; @@ -7414,9 +7398,8 @@ static void P_NiGHTSMovement(player_t *player) 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); if (!P_MobjWasRemoved(firstmobj)) { - firstmobj->destscale = player->mo->scale; P_SetTarget(&firstmobj->target, player->mo); - P_SetScale(firstmobj, player->mo->scale); + P_SetScale(firstmobj, player->mo->scale, true); // Superloop turns sparkles red if (player->powers[pw_nights_superloop]) P_SetMobjState(firstmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); @@ -7424,10 +7407,8 @@ static void P_NiGHTSMovement(player_t *player) 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); - + P_SetScale(secondmobj, player->mo->scale, true); // Superloop turns sparkles red if (player->powers[pw_nights_superloop]) P_SetMobjState(secondmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); @@ -7442,7 +7423,7 @@ static void P_NiGHTSMovement(player_t *player) { helpermobj->fuse = player->mo->fuse = leveltime; P_SetTarget(&helpermobj->target, player->mo); - P_SetScale(helpermobj, player->mo->scale); + P_SetScale(helpermobj, player->mo->scale, false); } } @@ -7645,8 +7626,7 @@ static void P_NiGHTSMovement(player_t *player) water->flags2 |= MF2_OBJECTFLIP; water->eflags |= MFE_VERTICALFLIP; } - water->destscale = player->mo->scale; - P_SetScale(water, player->mo->scale); + P_SetScale(water, player->mo->scale, true); } } @@ -7886,8 +7866,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) P_SetTarget(&flame->target, player->mo); flame->angle = travelangle + i*(ANGLE_MAX/numangles); flame->fuse = TICRATE*7; // takes about an extra second to hit the ground - flame->destscale = player->mo->scale; - P_SetScale(flame, player->mo->scale); + P_SetScale(flame, player->mo->scale, true); if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account flame->flags2 |= MF2_OBJECTFLIP; flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); @@ -7924,8 +7903,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) P_SetTarget(&flame->target, player->mo); flame->angle = travelangle; flame->fuse = TICRATE*6; - flame->destscale = player->mo->scale; - P_SetScale(flame, player->mo->scale); + P_SetScale(flame, player->mo->scale, true); if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account flame->flags2 |= MF2_OBJECTFLIP; flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); @@ -7973,8 +7951,7 @@ void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound) } particle->tics = 10; - particle->destscale = (2*mo->scale)/3; - P_SetScale(particle, particle->destscale); + P_SetScale(particle, (2*mo->scale)/3, true); P_SetObjectMomZ(particle, FRACUNIT, false); if (mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version @@ -8563,8 +8540,7 @@ void P_MovePlayer(player_t *player) water->flags2 |= MF2_OBJECTFLIP; water->eflags |= MFE_VERTICALFLIP; } - water->destscale = player->mo->scale; - P_SetScale(water, player->mo->scale); + P_SetScale(water, player->mo->scale, true); } } @@ -10998,8 +10974,7 @@ static void P_SpawnSparks(mobj_t *mo, angle_t maindir) spark->momz = mo->momz + r3; P_Thrust(spark, R_PointToAngle2(mo->x, mo->y, spark->x, spark->y), 8*FRACUNIT); - P_SetScale(spark, FRACUNIT/4); - spark->destscale = spark->scale; + P_SetScale(spark, FRACUNIT/4, true); spark->fuse = TICRATE/3; } @@ -11470,8 +11445,9 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails) tails->threshold = player->mo->z; tails->movecount = player->panim; tails->angle = horizangle; - P_SetScale(tails, player->mo->scale); + P_SetScale(tails, player->mo->scale, false); tails->destscale = player->mo->destscale; + tails->old_scale = player->mo->old_scale; tails->radius = player->mo->radius; tails->height = player->mo->height; zoffs = FixedMul(zoffs, tails->scale); @@ -11562,7 +11538,9 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume) y = mo->y + radiusY + FixedMul(offsetH, factorY); z = mo->z + heightoffset + offsetV; bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE); - bubble->scale = mo->scale >> 1; + P_SetScale(bubble, mo->scale/2, true); + bubble->destscale = mo->scale; + bubble->scalespeed = FixedMul(bubble->scalespeed, mo->scale); P_SetTarget(&bubble->dontdrawforviewmobj, mo); // Hide the bubble in first-person } @@ -11583,7 +11561,7 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume) if (stat == fume->info->spawnstate) // If currently inivisble, activate! { P_SetMobjState(fume, (stat = fume->info->seestate)); - P_SetScale(fume, mo->scale); + P_SetScale(fume, mo->scale, false); resetinterp = true; } @@ -11598,7 +11576,7 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume) if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount) // If just about to enter dashmode, play the startup animation again { P_SetMobjState(fume, (stat = fume->info->seestate)); - P_SetScale(fume, mo->scale << 1); + P_SetScale(fume, 2*mo->scale, true); } fume->flags2 = (fume->flags2 & ~MF2_DONTDRAW) | (mo->flags2 & MF2_DONTDRAW); fume->destscale = (mo->scale + FixedDiv(player->speed, player->normalspeed)) / (underwater ? 6 : 3); diff --git a/src/r_skins.c b/src/r_skins.c index 1605ca6c8..57e009a2e 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -374,7 +374,7 @@ static void SetSkin(player_t *player, INT32 skinnum) player->mo->skin = skin; if (newcolor) player->mo->color = newcolor; - P_SetScale(player->mo, player->mo->scale); + P_SetScale(player->mo, player->mo->scale, false); player->mo->radius = radius; P_SetMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames From a4cb3960ce842a6e3ec521694f29f9f44d52cc67 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Tue, 2 Jan 2024 17:51:47 +0100 Subject: [PATCH 02/18] Set old sprite scales and offsets for ghost mobjs --- src/p_mobj.c | 4 ++++ src/p_mobj.h | 8 ++++---- src/p_user.c | 4 ++++ src/r_fps.c | 8 ++++++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 06287091a..7696a3803 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14443,9 +14443,13 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo newmobj->old_scale2 = mobj->old_scale2; newmobj->old_scale = mobj->old_scale; + newmobj->old_spritexscale2 = mobj->old_spritexscale2; newmobj->old_spritexscale = mobj->old_spritexscale; + newmobj->old_spriteyscale2 = mobj->old_spriteyscale2; newmobj->old_spriteyscale = mobj->old_spriteyscale; + newmobj->old_spritexoffset2 = mobj->old_spritexoffset2; newmobj->old_spritexoffset = mobj->old_spritexoffset; + newmobj->old_spriteyoffset2 = mobj->old_spriteyoffset2; newmobj->old_spriteyoffset = mobj->old_spriteyoffset; return newmobj; diff --git a/src/p_mobj.h b/src/p_mobj.h index bc6601ea3..573e3ef8b 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -302,8 +302,8 @@ typedef struct mobj_s INT32 blendmode; // blend mode fixed_t spritexscale, spriteyscale; fixed_t spritexoffset, spriteyoffset; - fixed_t old_spritexscale, old_spriteyscale; - fixed_t old_spritexoffset, old_spriteyoffset; + fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2; + fixed_t old_spritexoffset, old_spriteyoffset, old_spritexoffset2, old_spriteyoffset2; struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears @@ -441,8 +441,8 @@ typedef struct precipmobj_s INT32 blendmode; // blend mode fixed_t spritexscale, spriteyscale; fixed_t spritexoffset, spriteyoffset; - fixed_t old_spritexscale, old_spriteyscale; - fixed_t old_spritexoffset, old_spriteyoffset; + fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2; + fixed_t old_spritexoffset, old_spriteyoffset, old_spritexoffset2, old_spriteyoffset2; struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears diff --git a/src/p_user.c b/src/p_user.c index 0037845c0..6fc8d4fac 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2095,6 +2095,10 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->old_pitch = mobj->old_pitch2; ghost->old_roll = mobj->old_roll2; ghost->old_spriteroll = mobj->old_spriteroll2; + ghost->old_spritexscale = mobj->old_spritexscale2; + ghost->old_spriteyscale = mobj->old_spriteyscale2; + ghost->old_spritexoffset = mobj->old_spritexoffset2; + ghost->old_spriteyoffset = mobj->old_spriteyoffset2; ghost->old_scale = mobj->old_scale2; return ghost; diff --git a/src/r_fps.c b/src/r_fps.c index de450aaa7..6a3967cbc 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -799,6 +799,10 @@ void R_ResetMobjInterpolationState(mobj_t *mobj) mobj->old_roll2 = mobj->old_roll; mobj->old_spriteroll2 = mobj->old_spriteroll; mobj->old_scale2 = mobj->old_scale; + mobj->old_spritexscale2 = mobj->old_spritexscale; + mobj->old_spriteyscale2 = mobj->old_spriteyscale; + mobj->old_spritexoffset2 = mobj->old_spritexoffset; + mobj->old_spriteyoffset2 = mobj->old_spriteyoffset; mobj->old_x = mobj->x; mobj->old_y = mobj->y; mobj->old_z = mobj->z; @@ -835,6 +839,10 @@ void R_ResetPrecipitationMobjInterpolationState(precipmobj_t *mobj) mobj->old_pitch2 = mobj->old_pitch; mobj->old_roll2 = mobj->old_roll; mobj->old_spriteroll2 = mobj->old_spriteroll; + mobj->old_spritexscale2 = mobj->old_spritexscale; + mobj->old_spriteyscale2 = mobj->old_spriteyscale; + mobj->old_spritexoffset2 = mobj->old_spritexoffset; + mobj->old_spriteyoffset2 = mobj->old_spriteyoffset; mobj->old_x = mobj->x; mobj->old_y = mobj->y; mobj->old_z = mobj->z; From c46f861034a310e9f4d807116115fe593b75dbca Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Thu, 4 Jan 2024 08:29:30 +0100 Subject: [PATCH 03/18] New gamepad defaults, with Shield on B --- src/g_input.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/g_input.c b/src/g_input.c index 3f1be37ba..fdbadf6af 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -743,34 +743,34 @@ void G_DefineDefaultControls(void) // Gamepad controls -- same for both schemes gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+0; // A gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+2; // X - gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B - gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y - gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick - gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+4; // LB + gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+1; // B + gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+3; // Y + gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+4; // LB gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB + gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick + gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+9; // Right Stick gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start + gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_HAT1+0; // D-Pad Up + gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+1; // D-Pad Down gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right - gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick - gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up - gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_HAT1+1; // D-Pad Down // Second player controls only have joypad defaults gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A gamecontrolbisdefault[i][GC_SPIN ][1] = KEY_2JOY1+2; // X - gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B - gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y - gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick - gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+4; // LB + gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+1; // B + gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+3; // Y + gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+4; // LB gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB + gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick + gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+9; // Right Stick //gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back //gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start + gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2HAT1+0; // D-Pad Up + gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+1; // D-Pad Down gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right - gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick - gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up - gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2HAT1+1; // D-Pad Down } } From 634c972f6c72bbdd8130abdd4def92792022ae16 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sun, 11 Feb 2024 12:08:42 +0100 Subject: [PATCH 04/18] Fix console not being blocked by IT_CV_STRING --- 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 504a5c6cb..6f220d243 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3425,7 +3425,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; if (M_ChangeStringCvar(ch)) return true; From bdeec562704883943de90b6425d3b7de76f25f97 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 11 Feb 2024 13:30:15 +0100 Subject: [PATCH 05/18] Substitute MT_NULL with MT_RAY in Lua --- src/lua_baselib.c | 55 +++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b70c63ece..63bdb4d34 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -44,6 +44,21 @@ return luaL_error(L, "HUD rendering code should not call this function!");\ else if (hook_cmd_running)\ return luaL_error(L, "CMD building code should not call this function!"); +#define NOSPAWNNULL if (type >= NUMMOBJTYPES)\ +return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);\ +else if (type == MT_NULL)\ +{\ + if (!nospawnnull_seen) {\ + nospawnnull_seen = true;\ + CONS_Alert(CONS_WARNING,"Spawning an \"MT_NULL\" mobj is deprecated and will be removed.\nUse \"MT_RAY\" instead.\n");\ + }\ +type = MT_RAY;\ +} +static boolean nospawnnull_seen = false; // TODO: 2.3: Delete +// TODO: 2.3: Use the below NOSPAWNNULL define instead. P_SpawnMobj used to say "if MT_NULL, use MT_RAY instead", so the above define maintains Lua script compatibility until v2.3 +/*#define NOSPAWNNULL if (type <= MT_NULL || type >= NUMMOBJTYPES)\ +return luaL_error(L, "mobj type %d out of range (1 - %d)", type, NUMMOBJTYPES-1);*/ + boolean luaL_checkboolean(lua_State *L, int narg) { luaL_checktype(L, narg, LUA_TBOOLEAN); return lua_toboolean(L, narg); @@ -625,8 +640,7 @@ static int lib_pSpawnMobj(lua_State *L) mobjtype_t type = luaL_checkinteger(L, 4); NOHUD INLEVEL - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); + NOSPAWNNULL LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ); return 1; } @@ -640,10 +654,9 @@ static int lib_pSpawnMobjFromMobj(lua_State *L) mobjtype_t type = luaL_checkinteger(L, 5); NOHUD INLEVEL + NOSPAWNNULL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); return 1; } @@ -708,10 +721,9 @@ static int lib_pSpawnMissile(lua_State *L) mobjtype_t type = luaL_checkinteger(L, 3); NOHUD INLEVEL + NOSPAWNNULL if (!source || !dest) return LUA_ErrInvalid(L, "mobj_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ); return 1; } @@ -726,10 +738,9 @@ static int lib_pSpawnXYZMissile(lua_State *L) fixed_t z = luaL_checkfixed(L, 6); NOHUD INLEVEL + NOSPAWNNULL if (!source || !dest) return LUA_ErrInvalid(L, "mobj_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ); return 1; } @@ -746,10 +757,9 @@ static int lib_pSpawnPointMissile(lua_State *L) fixed_t z = luaL_checkfixed(L, 8); NOHUD INLEVEL + NOSPAWNNULL if (!source) return LUA_ErrInvalid(L, "mobj_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ); return 1; } @@ -764,10 +774,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L) INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5); NOHUD INLEVEL + NOSPAWNNULL if (!source) return LUA_ErrInvalid(L, "mobj_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ); return 1; } @@ -795,10 +804,9 @@ static int lib_pSPMAngle(lua_State *L) UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0); NOHUD INLEVEL + NOSPAWNNULL if (!source) return LUA_ErrInvalid(L, "mobj_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ); return 1; } @@ -810,10 +818,9 @@ static int lib_pSpawnPlayerMissile(lua_State *L) UINT32 flags2 = (UINT32)luaL_optinteger(L, 3, 0); NOHUD INLEVEL + NOSPAWNNULL if (!source) return LUA_ErrInvalid(L, "mobj_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ); return 1; } @@ -844,8 +851,7 @@ static int lib_pWeaponOrPanel(lua_State *L) { mobjtype_t type = luaL_checkinteger(L, 1); //HUDSAFE - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); + NOSPAWNNULL lua_pushboolean(L, P_WeaponOrPanel(type)); return 1; } @@ -888,8 +894,7 @@ static int lib_pSpawnParaloop(lua_State *L) boolean spawncenter = lua_optboolean(L, 9); NOHUD INLEVEL - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); + NOSPAWNNULL if (nstate >= NUMSTATES) return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1); P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter); @@ -1761,10 +1766,9 @@ static int lib_pSpawnSpinMobj(lua_State *L) mobjtype_t type = luaL_checkinteger(L, 2); NOHUD INLEVEL + NOSPAWNNULL if (!player) return LUA_ErrInvalid(L, "player_t"); - if (type >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); P_SpawnSpinMobj(player, type); return 0; } @@ -2710,12 +2714,11 @@ static int lib_pFadeLight(lua_State *L) static int lib_pIsFlagAtBase(lua_State *L) { - mobjtype_t flag = luaL_checkinteger(L, 1); + mobjtype_t type = luaL_checkinteger(L, 1); //HUDSAFE INLEVEL - if (flag >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1); - lua_pushboolean(L, P_IsFlagAtBase(flag)); + NOSPAWNNULL + lua_pushboolean(L, P_IsFlagAtBase(type)); return 1; } From 98ba396dbcb45d7c056e8f6f765768df86a7604f Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Fri, 16 Feb 2024 17:28:55 -0300 Subject: [PATCH 06/18] Fix issues related to texture scaling --- src/hardware/hw_main.c | 562 +++++++++++++++++++++++------------------ src/p_setup.c | 2 - src/r_defs.h | 6 +- src/r_main.c | 55 +--- src/r_main.h | 5 +- src/r_segs.c | 308 +++++++++++++--------- src/r_things.c | 34 ++- src/r_things.h | 1 + src/tables.h | 2 +- 9 files changed, 541 insertions(+), 434 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 9c1a95c93..8c4651c04 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1034,6 +1034,191 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) return true; } +static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliphigh, fixed_t worldtop, fixed_t worldbottom, fixed_t worldhigh, fixed_t worldlow, fixed_t worldtopslope, fixed_t worldbottomslope, fixed_t worldhighslope, fixed_t worldlowslope, UINT32 lightnum, FOutVector *inWallVerts) +{ + FOutVector wallVerts[4]; + + FSurfaceInfo Surf; + Surf.PolyColor.s.alpha = 255; + + // Determine if it's visible + if (!HWR_BlendMidtextureSurface(&Surf)) + return; + + fixed_t texheight = FixedDiv(textureheight[gl_midtexture], abs(gl_sidedef->scaley_mid)); + INT32 repeats; + + if (gl_sidedef->repeatcnt) + repeats = 1 + gl_sidedef->repeatcnt; + else if (gl_linedef->flags & ML_WRAPMIDTEX) + { + fixed_t high, low; + + if (gl_frontsector->ceilingheight > gl_backsector->ceilingheight) + high = gl_backsector->ceilingheight; + else + high = gl_frontsector->ceilingheight; + + if (gl_frontsector->floorheight > gl_backsector->floorheight) + low = gl_frontsector->floorheight; + else + low = gl_backsector->floorheight; + + repeats = (high - low) / texheight; + if ((high - low) % texheight) + repeats++; // tile an extra time to fill the gap -- Monster Iestyn + } + else + repeats = 1; + + GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture); + float xscale = FixedToFloat(gl_sidedef->scalex_mid); + float 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) + // heights of the polygon, and h & l, are the final (clipped) + // poly coords. + fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; + fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope; + + // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, + // you must use the linedef's backsector to be correct + // From CB + if (gl_curline->polyseg) + { + // Change this when polyobjects support slopes + popentop = popentopslope = gl_curline->backsector->ceilingheight; + popenbottom = popenbottomslope = gl_curline->backsector->floorheight; + } + else + { + popentop = min(worldtop, worldhigh); + popenbottom = max(worldbottom, worldlow); + popentopslope = min(worldtopslope, worldhighslope); + popenbottomslope = max(worldbottomslope, worldlowslope); + } + + // Find the wall's coordinates + fixed_t midtexheight = texheight * repeats; + + fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, abs(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(gl_frontsector->floorheight, gl_backsector->floorheight) + rowoffset; + polytop = polybottom + midtexheight; + } + // Peg it to the ceiling + else + { + polytop = min(gl_frontsector->ceilingheight, gl_backsector->ceilingheight) + rowoffset; + polybottom = polytop - midtexheight; + } + + // The right side's coordinates are the the same as the left side + polytopslope = polytop; + polybottomslope = polybottom; + } + // Skew the texture, but peg it to the floor + else if (gl_linedef->flags & ML_MIDPEG) + { + polybottom = popenbottom + rowoffset; + polytop = polybottom + midtexheight; + polybottomslope = popenbottomslope + rowoffset; + polytopslope = polybottomslope + midtexheight; + } + // Skew it according to the ceiling's slope + else + { + polytop = popentop + rowoffset; + polybottom = polytop - midtexheight; + polytopslope = popentopslope + rowoffset; + polybottomslope = polytopslope - midtexheight; + } + + // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector + if (gl_curline->polyseg) + { + lowcut = polybottom; + highcut = polytop; + lowcutslope = polybottomslope; + highcutslope = polytopslope; + } + else + { + lowcut = popenbottom; + highcut = popentop; + lowcutslope = popenbottomslope; + highcutslope = popentopslope; + } + + fixed_t h = min(highcut, polytop); + fixed_t l = max(polybottom, lowcut); + fixed_t hS = min(highcutslope, polytopslope); + fixed_t lS = max(polybottomslope, lowcutslope); + + // PEGGING + fixed_t texturevpeg, texturevpegslope; + + if (gl_linedef->flags & ML_MIDPEG) + { + texturevpeg = midtexheight - h + polybottom; + texturevpegslope = midtexheight - hS + polybottomslope; + } + else + { + texturevpeg = polytop - h; + texturevpegslope = polytopslope - hS; + } + + memcpy(wallVerts, inWallVerts, sizeof(wallVerts)); + + // Left side + 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->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX; + + // Right side + 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->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX; + + // set top/bottom coords + // Take the texture peg into account, rather than changing the offsets past + // where the polygon might not be. + wallVerts[3].y = FIXED_TO_FLOAT(h); + wallVerts[0].y = FIXED_TO_FLOAT(l); + wallVerts[2].y = FIXED_TO_FLOAT(hS); + wallVerts[1].y = FIXED_TO_FLOAT(lS); + + // TODO: Actually use the surface's flags so that I don't have to do this + FUINT blendmode = Surf.PolyFlags; + + // Render midtextures on two-sided lines with a z-buffer offset. + // This will cause the midtexture appear on top, if a FOF overlaps with it. + blendmode |= PF_Decal; + + extracolormap_t *colormap = gl_frontsector->extra_colormap; + + if (gl_frontsector->numlights) + { + if (!(blendmode & PF_Masked)) + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode); + else + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode); + } + else if (!(blendmode & PF_Masked)) + HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap); + else + HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap); +} + // // HWR_ProcessSeg // A portion or all of a wall segment will be drawn, from startfrac to endfrac, @@ -1105,9 +1290,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].z = wallVerts[1].z = ve.y; // x offset the texture - fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset; - float cliplow = (float)texturehpeg; - float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT)); + float cliplow = (float)gl_curline->offset; + float cliphigh = cliplow + (gl_curline->flength * FRACUNIT); FUINT lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); extracolormap_t *colormap = gl_frontsector->extra_colormap; @@ -1122,6 +1306,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (gl_backsector) { INT32 gl_toptexture = 0, gl_bottomtexture = 0; + fixed_t texturevpeg; SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight) @@ -1151,30 +1336,46 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) { grTex = HWR_GetTexture(gl_toptexture); - xscale = FixedToFloat(gl_sidedef->scalex_top); - yscale = FixedToFloat(gl_sidedef->scaley_top); + xscale = FixedToFloat(abs(gl_sidedef->scalex_top)); + yscale = FixedToFloat(abs(gl_sidedef->scaley_top)); - fixed_t texheight = FixedDiv(textureheight[gl_toptexture], gl_sidedef->scaley_top); + fixed_t offsetx_top = gl_sidedef->textureoffset + gl_sidedef->offsetx_top; + + float left = cliplow * xscale; + float right = cliphigh * xscale; + if (gl_sidedef->scalex_top < 0) + { + left = -left; + right = -right; + offsetx_top = -offsetx_top; + } + + fixed_t texheight = textureheight[gl_toptexture]; + fixed_t texheightscaled = FixedDiv(texheight, abs(gl_sidedef->scaley_top)); // PEGGING + // FIXME: This is probably not correct? if (gl_linedef->flags & ML_DONTPEGTOP) texturevpeg = 0; else if (gl_linedef->flags & ML_SKEWTD) texturevpeg = worldhigh + texheight - worldtop; else - texturevpeg = gl_backsector->ceilingheight + texheight - gl_frontsector->ceilingheight; + texturevpeg = gl_backsector->ceilingheight + texheightscaled - gl_frontsector->ceilingheight; texturevpeg *= yscale; - texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; + if (gl_sidedef->scaley_top < 0) + texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_top; + else + 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; + texturevpeg %= texheightscaled; 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; + wallVerts[0].s = wallVerts[3].s = (left + offsetx_top) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (right + offsetx_top) * grTex->scaleX; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) @@ -1199,6 +1400,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY; } + if (gl_sidedef->scaley_top < 0) + { + wallVerts[0].t = -wallVerts[0].t; + wallVerts[1].t = -wallVerts[1].t; + wallVerts[2].t = -wallVerts[2].t; + wallVerts[3].t = -wallVerts[3].t; + } + // set top/bottom coords wallVerts[3].y = FIXED_TO_FLOAT(worldtop); wallVerts[0].y = FIXED_TO_FLOAT(worldhigh); @@ -1217,8 +1426,19 @@ 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_bottom); - yscale = FixedToFloat(gl_sidedef->scaley_bottom); + xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom)); + yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom)); + + fixed_t offsetx_bottom = gl_sidedef->textureoffset + gl_sidedef->offsetx_bottom; + + float left = cliplow * xscale; + float right = cliphigh * xscale; + if (gl_sidedef->scalex_bottom < 0) + { + left = -left; + right = -right; + offsetx_bottom = -offsetx_bottom; + } // PEGGING if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) @@ -1230,15 +1450,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpeg *= yscale; - texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom; + if (gl_sidedef->scaley_bottom < 0) + texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_bottom; + else + 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_bottom); + texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], abs(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_bottom) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (left + offsetx_bottom) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (right + offsetx_bottom) * grTex->scaleX; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) @@ -1262,6 +1485,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY; } + if (gl_sidedef->scaley_bottom < 0) + { + wallVerts[0].t = -wallVerts[0].t; + wallVerts[1].t = -wallVerts[1].t; + wallVerts[2].t = -wallVerts[2].t; + wallVerts[3].t = -wallVerts[3].t; + } + // set top/bottom coords wallVerts[3].y = FIXED_TO_FLOAT(worldlow); wallVerts[0].y = FIXED_TO_FLOAT(worldbottom); @@ -1276,196 +1507,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } - // Render midtexture if there's one. Determine if it's visible first, though - if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) - { - sector_t *front, *back; - fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid); - INT32 repeats; + // Render midtexture if there's one + if (gl_midtexture) + HWR_RenderMidtexture(gl_midtexture, cliplow, cliphigh, worldtop, worldbottom, worldhigh, worldlow, worldtopslope, worldbottomslope, worldhighslope, worldlowslope, lightnum, wallVerts); - if (gl_linedef->frontsector->heightsec != -1) - front = §ors[gl_linedef->frontsector->heightsec]; - else - front = gl_linedef->frontsector; - - if (gl_linedef->backsector->heightsec != -1) - back = §ors[gl_linedef->backsector->heightsec]; - else - back = gl_linedef->backsector; - - if (gl_sidedef->repeatcnt) - repeats = 1 + gl_sidedef->repeatcnt; - else if (gl_linedef->flags & ML_WRAPMIDTEX) - { - fixed_t high, low; - - if (front->ceilingheight > back->ceilingheight) - high = back->ceilingheight; - else - high = front->ceilingheight; - - if (front->floorheight > back->floorheight) - low = front->floorheight; - else - low = back->floorheight; - - repeats = (high - low) / texheight; - if ((high - low) % texheight) - repeats++; // tile an extra time to fill the gap -- Monster Iestyn - } - 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) - // heights of the polygon, and h & l, are the final (clipped) - // poly coords. - fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; - fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope; - - // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, - // you must use the linedef's backsector to be correct - // From CB - if (gl_curline->polyseg) - { - popentop = popentopslope = back->ceilingheight; - popenbottom = popenbottomslope = back->floorheight; - } - else - { - popentop = min(worldtop, worldhigh); - popenbottom = max(worldbottom, worldlow); - popentopslope = min(worldtopslope, worldhighslope); - popenbottomslope = max(worldbottomslope, worldlowslope); - } - - // 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) + rowoffset; - polytop = polybottom + midtexheight; - } - // Peg it to the ceiling - else - { - polytop = min(front->ceilingheight, back->ceilingheight) + rowoffset; - polybottom = polytop - midtexheight; - } - - // The right side's coordinates are the the same as the left side - polytopslope = polytop; - polybottomslope = polybottom; - } - // Skew the texture, but peg it to the floor - else if (gl_linedef->flags & ML_MIDPEG) - { - polybottom = popenbottom + rowoffset; - polytop = polybottom + midtexheight; - polybottomslope = popenbottomslope + rowoffset; - polytopslope = polybottomslope + midtexheight; - } - // Skew it according to the ceiling's slope - else - { - polytop = popentop + rowoffset; - polybottom = polytop - midtexheight; - polytopslope = popentopslope + rowoffset; - polybottomslope = polytopslope - midtexheight; - } - - // CB - // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, - // you must use the linedef's backsector to be correct - if (gl_curline->polyseg) - { - lowcut = polybottom; - highcut = polytop; - lowcutslope = polybottomslope; - highcutslope = polytopslope; - } - else - { - // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector - lowcut = popenbottom; - highcut = popentop; - lowcutslope = popenbottomslope; - highcutslope = popentopslope; - } - - h = min(highcut, polytop); - l = max(polybottom, lowcut); - hS = min(highcutslope, polytopslope); - lS = max(polybottomslope, lowcutslope); - - // PEGGING - fixed_t texturevpegslope; - - if (gl_linedef->flags & ML_MIDPEG) - { - texturevpeg = midtexheight - h + polybottom; - texturevpegslope = midtexheight - hS + polybottomslope; - } - else - { - texturevpeg = polytop - h; - texturevpegslope = polytopslope - hS; - } - - // Left side - 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 * 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 - // where the polygon might not be. - wallVerts[3].y = FIXED_TO_FLOAT(h); - wallVerts[0].y = FIXED_TO_FLOAT(l); - wallVerts[2].y = FIXED_TO_FLOAT(hS); - wallVerts[1].y = FIXED_TO_FLOAT(lS); - - // TODO: Actually use the surface's flags so that I don't have to do this - FUINT blendmode = Surf.PolyFlags; - - // Render midtextures on two-sided lines with a z-buffer offset. - // This will cause the midtexture appear on top, if a FOF overlaps with it. - blendmode |= PF_Decal; - - if (gl_frontsector->numlights) - { - if (!(blendmode & PF_Masked)) - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode); - else - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode); - } - else if (!(blendmode & PF_Masked)) - HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap); - else - HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap); - } - - // Sky culling - // No longer so much a mess as before! if (!gl_curline->polyseg) // Don't do it for polyobjects { + // Sky culling + // No longer so much a mess as before! if (gl_frontsector->ceilingpic == skyflatnum && gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky { @@ -1509,8 +1558,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom 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; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX; // Texture correction for slopes if (gl_linedef->flags & ML_NOSKEW) { @@ -1573,8 +1622,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Used for height comparisons and etc across FOFs and slopes fixed_t high1, highslope1, low1, lowslope1; + fixed_t texturehpeg = gl_sidedef->textureoffset + gl_sidedef->offsetx_mid; + INT32 texnum; - line_t * newline = NULL; // Multi-Property FOF lowcut = max(worldbottom, worldlow); highcut = min(worldtop, worldhigh); @@ -1608,16 +1658,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; - side_t *side = &sides[rover->master->sidenum[0]]; + side_t *side = R_GetFFloorSide(gl_curline, rover); boolean do_texture_skew; boolean dont_peg_bottom; if (rover->master->flags & ML_TFERLINE) { - size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; - newline = rover->master->frontsector->lines[0] + linenum; - side = &sides[newline->sidenum[0]]; + line_t *newline = R_GetFFloorLine(gl_curline, rover); do_texture_skew = newline->flags & ML_SKEWTD; dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM; } @@ -1695,14 +1743,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } } - 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; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX; } + FBITFIELD blendmode; + if (rover->fofflags & FOF_FOG) { - FBITFIELD blendmode; - blendmode = PF_Fog|PF_NoTexture; lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); @@ -1717,7 +1765,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } else { - FBITFIELD blendmode = PF_Masked; + blendmode = PF_Masked; if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) { @@ -1765,13 +1813,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; - side_t *side = &sides[rover->master->sidenum[0]]; + side_t *side = R_GetFFloorSide(gl_curline, rover); + + boolean do_texture_skew; + boolean dont_peg_bottom; if (rover->master->flags & ML_TFERLINE) { - size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; - newline = rover->master->frontsector->lines[0] + linenum; - side = &sides[newline->sidenum[0]]; + line_t *newline = R_GetFFloorLine(gl_curline, rover); + do_texture_skew = newline->flags & ML_SKEWTD; + dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM; + } + else + { + do_texture_skew = rover->master->flags & ML_SKEWTD; + dont_peg_bottom = gl_curline->linedef->flags & ML_DONTPEGBOTTOM; } texnum = R_GetTextureNum(side->midtexture); @@ -1808,23 +1864,49 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } else { + // 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 + fixed_t texturevpeg = side->rowoffset + side->offsety_mid; + grTex = HWR_GetTexture(texnum); xscale = FixedToFloat(side->scalex_mid); yscale = FixedToFloat(side->scaley_mid); - fixed_t diff = (*rover->topheight - h) * yscale; + if (!do_texture_skew) // no skewing + { + if (dont_peg_bottom) + texturevpeg -= (*rover->topheight - *rover->bottomheight) * yscale; - 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[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 (!dont_peg_bottom) // skew by top + { + 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 * 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 * xscale) + side->offsetx_mid) * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX; } + FBITFIELD blendmode; + if (rover->fofflags & FOF_FOG) { - FBITFIELD blendmode; - blendmode = PF_Fog|PF_NoTexture; lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); @@ -1839,7 +1921,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } else { - FBITFIELD blendmode = PF_Masked; + blendmode = PF_Masked; if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) { @@ -2656,36 +2738,14 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) static inline void HWR_AddPolyObjectSegs(void) { size_t i, j; - seg_t *gl_fakeline = Z_Calloc(sizeof(seg_t), PU_STATIC, NULL); - polyvertex_t *pv1 = Z_Calloc(sizeof(polyvertex_t), PU_STATIC, NULL); - polyvertex_t *pv2 = Z_Calloc(sizeof(polyvertex_t), PU_STATIC, NULL); // Sort through all the polyobjects for (i = 0; i < numpolys; ++i) { // Render the polyobject's lines for (j = 0; j < po_ptrs[i]->segCount; ++j) - { - // Copy the info of a polyobject's seg, then convert it to OpenGL floating point - M_Memcpy(gl_fakeline, po_ptrs[i]->segs[j], sizeof(seg_t)); - - // Now convert the line to float and add it to be rendered - pv1->x = FIXED_TO_FLOAT(gl_fakeline->v1->x); - pv1->y = FIXED_TO_FLOAT(gl_fakeline->v1->y); - pv2->x = FIXED_TO_FLOAT(gl_fakeline->v2->x); - pv2->y = FIXED_TO_FLOAT(gl_fakeline->v2->y); - - gl_fakeline->pv1 = pv1; - gl_fakeline->pv2 = pv2; - - HWR_AddLine(gl_fakeline); - } + HWR_AddLine(po_ptrs[i]->segs[j]); } - - // Free temporary data no longer needed - Z_Free(pv2); - Z_Free(pv1); - Z_Free(gl_fakeline); } static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, diff --git a/src/p_setup.c b/src/p_setup.c index 1d985beb4..3bde51c3b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3290,8 +3290,6 @@ static void P_InitializeSeg(seg_t *seg) seg->lightmaps = NULL; // list of static lightmap for this seg #endif - seg->numlights = 0; - seg->rlights = NULL; seg->polyseg = NULL; seg->dontrenderme = false; } diff --git a/src/r_defs.h b/src/r_defs.h index d556b540f..899d6ad73 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -742,9 +742,6 @@ typedef struct seg_s lightmap_t *lightmaps; // for static lightmap #endif - // Why slow things down by calculating lightlists for every thick side? - size_t numlights; - r_lightlist_t *rlights; polyobj_t *polyseg; boolean dontrenderme; boolean glseg; @@ -828,6 +825,7 @@ typedef struct drawseg_s INT16 *sprtopclip; INT16 *sprbottomclip; fixed_t *maskedtexturecol; + fixed_t *maskedtextureheight; // For handling sloped midtextures fixed_t *invscale; struct visplane_s *ffloorplanes[MAXFFLOORS]; @@ -839,8 +837,6 @@ typedef struct drawseg_s UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping - fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures - vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes } drawseg_t; diff --git a/src/r_main.c b/src/r_main.c index aaab234ad..c920031a0 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -318,7 +318,6 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y) } // This version uses 64-bit variables to avoid overflows with large values. -// Currently used only by OpenGL rendering. angle_t R_PointToAngle64(INT64 x, INT64 y) { return (y -= viewy, (x -= viewx) || y) ? @@ -384,56 +383,26 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y) return R_PointToDist2(viewx, viewy, x, y); } -angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) +line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor) { - INT64 dx = x1-x2; - INT64 dy = y1-y2; - if (dx < INT32_MIN || dx > INT32_MAX || dy < INT32_MIN || dy > INT32_MAX) + if (pfloor->master->flags & ML_TFERLINE) { - x1 = (int)(dx / 2 + x2); - y1 = (int)(dy / 2 + y2); + size_t linenum = seg->linedef - pfloor->target->lines[0]; + return pfloor->master->frontsector->lines[0] + linenum; } - return (y1 -= y2, (x1 -= x2) || y1) ? - x1 >= 0 ? - y1 >= 0 ? - (x1 > y1) ? tantoangle[SlopeDivEx(y1,x1)] : // octant 0 - ANGLE_90-tantoangle[SlopeDivEx(x1,y1)] : // octant 1 - x1 > (y1 = -y1) ? 0-tantoangle[SlopeDivEx(y1,x1)] : // octant 8 - ANGLE_270+tantoangle[SlopeDivEx(x1,y1)] : // octant 7 - y1 >= 0 ? (x1 = -x1) > y1 ? ANGLE_180-tantoangle[SlopeDivEx(y1,x1)] : // octant 3 - ANGLE_90 + tantoangle[SlopeDivEx(x1,y1)] : // octant 2 - (x1 = -x1) > (y1 = -y1) ? ANGLE_180+tantoangle[SlopeDivEx(y1,x1)] : // octant 4 - ANGLE_270-tantoangle[SlopeDivEx(x1,y1)] : // octant 5 - 0; + else + return pfloor->master; } -// -// R_ScaleFromGlobalAngle -// Returns the texture mapping scale for the current line (horizontal span) -// at the given angle. -// rw_distance must be calculated first. -// -// killough 5/2/98: reformatted, cleaned up -// -// note: THIS IS USED ONLY FOR WALLS! -fixed_t R_ScaleFromGlobalAngle(angle_t visangle) +side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor) { - angle_t anglea = ANGLE_90 + (visangle-viewangle); - angle_t angleb = ANGLE_90 + (visangle-rw_normalangle); - fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT)); - // proff 11/06/98: Changed for high-res - fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT)); - - if (den > num>>16) + if (pfloor->master->flags & ML_TFERLINE) { - num = FixedDiv(num, den); - if (num > 64*FRACUNIT) - return 64*FRACUNIT; - if (num < 256) - return 256; - return num; + line_t *newline = R_GetFFloorLine(seg, pfloor); + return &sides[newline->sidenum[0]]; } - return 64*FRACUNIT; + else + return &sides[pfloor->master->sidenum[0]]; } // diff --git a/src/r_main.h b/src/r_main.h index c7dc06c90..da2189328 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -77,17 +77,18 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line); angle_t R_PointToAngle(fixed_t x, fixed_t y); angle_t R_PointToAngle64(INT64 x, INT64 y); angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); -angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); 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); boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph); +line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor); +side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor); + // Render stats extern precise_t ps_prevframetime;// time when previous frame was rendered diff --git a/src/r_segs.c b/src/r_segs.c index 267c1d47d..b5d4a6dae 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -16,15 +16,10 @@ #include "r_sky.h" #include "r_portal.h" -#include "r_splats.h" #include "w_wad.h" #include "z_zone.h" -#include "netcode/d_netcmd.h" -#include "m_misc.h" -#include "p_local.h" // Camera... #include "p_slopes.h" -#include "console.h" // con_clipviewtop #include "taglist.h" // OPTIMIZE: closed two sided lines as single sided @@ -79,6 +74,8 @@ static fixed_t *maskedtextureheight = NULL; static fixed_t *thicksidecol = NULL; static fixed_t *invscale = NULL; +static boolean texcoltables; + //SoM: 3/23/2000: Use boom opening limit removal static size_t numopenings; static INT16 *openings, *lastopening; @@ -92,10 +89,6 @@ void R_ClearSegTables(void) curtexturecolumntable = texturecolumntable; } -// ========================================================================== -// R_RenderMaskedSegRange -// ========================================================================== - transnum_t R_GetLinedefTransTable(fixed_t alpha) { return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1); @@ -115,8 +108,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) INT32 times, repeats; INT64 overflow_test; INT32 range; + UINT8 vertflip; unsigned lengthcol; + fixed_t wall_scaley; + fixed_t scalestep; + fixed_t scale1; + // Calculate light table. // Use different light tables // for horizontal / vertical / diagonal. Diagonal? @@ -164,9 +162,17 @@ 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); + vertflip = textures[texnum]->flip & 2; + + wall_scaley = sidedef->scaley_mid; + if (wall_scaley < 0) + { + wall_scaley = -wall_scaley; + vertflip = !vertflip; + } + + scalestep = FixedDiv(ds->scalestep, wall_scaley); + scale1 = FixedDiv(ds->scale1, wall_scaley); range = max(ds->x2-ds->x1, 1); rw_scalestep = scalestep; @@ -175,7 +181,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // Texture must be cached R_CheckTextureCache(texnum); - if (textures[texnum]->flip & 2) // vertically flipped? + if (vertflip) // vertically flipped? colfunc_2s = R_DrawFlippedMaskedColumn; else colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture @@ -469,6 +475,11 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) return false; } +static fixed_t R_GetSlopeTextureSlide(pslope_t *slope, angle_t lineangle) +{ + return FixedMul(slope->zdelta, FINECOSINE((lineangle-slope->xydirection)>>ANGLETOFINESHIFT)); +} + // // R_RenderThickSideRange // Renders all the thick sides in the given range. @@ -484,8 +495,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) sector_t tempsec; INT32 templight; INT32 i, p; - fixed_t bottombounds = viewheight << FRACBITS; - fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; fixed_t offsetvalue; lightlist_t *light; r_lightlist_t *rlight; @@ -495,12 +504,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT64 top_frac, top_step, bottom_frac, bottom_step; // skew FOF walls with slopes? fixed_t ffloortextureslide = 0; - INT32 oldx = -1; + fixed_t oldtexturecolumn = -1; fixed_t left_top, left_bottom; // needed here for slope skewing pslope_t *skewslope = NULL; boolean do_texture_skew; boolean dont_peg_bottom; + fixed_t wall_offsetx; fixed_t wall_scalex, wall_scaley; + UINT8 vertflip; unsigned lengthcol; void (*colfunc_2s) (column_t *, unsigned); @@ -513,15 +524,13 @@ 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; - sidedef = &sides[pfloor->master->sidenum[0]]; + sidedef = R_GetFFloorSide(curline, pfloor); colfunc = colfuncs[BASEDRAWFUNC]; if (pfloor->master->flags & ML_TFERLINE) { - size_t linenum = curline->linedef-backsector->lines[0]; - line_t *newline = pfloor->master->frontsector->lines[0] + linenum; - sidedef = &sides[newline->sidenum[0]]; + line_t *newline = R_GetFFloorLine(curline, pfloor); do_texture_skew = newline->flags & ML_SKEWTD; dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM; } @@ -532,6 +541,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } texnum = R_GetTextureNum(sidedef->midtexture); + vertflip = textures[texnum]->flip & 2; if (pfloor->fofflags & FOF_TRANSLUCENT) { @@ -685,18 +695,25 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) wall_scalex = FixedDiv(FRACUNIT, sidedef->scalex_mid); wall_scaley = sidedef->scaley_mid; + if (wall_scaley < 0) + { + wall_scaley = -wall_scaley; + vertflip = !vertflip; + } thicksidecol = ffloortexturecolumn; + wall_offsetx = ds->offsetx + sidedef->offsetx_mid; + if (wall_scalex == FRACUNIT) { for (INT32 x = x1; x <= x2; x++) - thicksidecol[x] = ds->thicksidecol[x] + ds->offsetx; + thicksidecol[x] = ds->thicksidecol[x]; } else { for (INT32 x = x1; x <= x2; x++) - thicksidecol[x] = FixedDiv(ds->thicksidecol[x], wall_scalex) + ds->offsetx; + thicksidecol[x] = FixedDiv(ds->thicksidecol[x], wall_scalex); } mfloorclip = ds->sprbottomclip; @@ -731,7 +748,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (skewslope) { angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley); } dc_texturemid += offsetvalue; @@ -739,7 +756,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Texture must be cached R_CheckTextureCache(texnum); - if (textures[texnum]->flip & 2) // vertically flipped? + if (vertflip) // vertically flipped? colfunc_2s = R_DrawRepeatFlippedMaskedColumn; else colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture @@ -773,9 +790,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // skew FOF walls if (ffloortextureslide) { - if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, thicksidecol[oldx]-thicksidecol[dc_x]); - oldx = dc_x; + if (oldtexturecolumn != -1) + dc_texturemid += FixedMul(ffloortextureslide, oldtexturecolumn-ds->thicksidecol[dc_x]); + oldtexturecolumn = ds->thicksidecol[dc_x]; } // Calculate bounds @@ -791,7 +808,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) bottom_frac += bottom_step; // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) + if (windowbottom < 0 || windowtop > (viewheight << FRACBITS)) { if (dc_numlights) { @@ -810,7 +827,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley); // Get data for the column - col = R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS)); + col = R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS)); // SoM: New code does not rely on R_DrawColumnShadowed_8 which // will (hopefully) put less strain on the stack. @@ -984,36 +1001,64 @@ static boolean R_FFloorCanClip(visffloor_t *pfloor) #define HEIGHTBITS 12 #define HEIGHTUNIT (1<colormap + (xwalllights[pindex] - colormaps); else dc_lightlist[i].rcolormap = xwalllights[pindex]; - - colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; } } @@ -1252,24 +1295,9 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = yh; dc_texturemid = rw_midtexturemid; - dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_midtexturescaley); - dc_source = R_GetColumn(midtexture, offset >> FRACBITS)->pixels; dc_texheight = textureheight[midtexture]>>FRACBITS; - - //profile stuff --------------------------------------------------------- -#ifdef TIMING - ProfZeroTimer(); -#endif - colfunc(); -#ifdef TIMING - RDMSR(0x10,&mycount); - mytotal += mycount; //64bit add - - if (nombre--==0) - I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1), - (INT32)mytotal); -#endif - //profile stuff --------------------------------------------------------- + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, midscaley); + drawmiddle(R_GetColumn(midtexture, offset >> FRACBITS)->pixels, dc_texheight); // dont draw anything more for this column, since // a midtexture blocks the view @@ -1321,10 +1349,9 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = mid; dc_texturemid = rw_toptexturemid; - dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_toptexturescaley); - dc_source = R_GetColumn(toptexture, offset >> FRACBITS)->pixels; dc_texheight = textureheight[toptexture]>>FRACBITS; - colfunc(); + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, topscaley); + drawtop(R_GetColumn(toptexture, offset >> FRACBITS)->pixels, dc_texheight); ceilingclip[rw_x] = (INT16)mid; } else if (!rw_ceilingmarked) // entirely off top of screen @@ -1334,8 +1361,8 @@ static void R_RenderSegLoop (void) ceilingclip[rw_x] = topclip; if (oldtexturecolumn_top != -1) - rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-toptexturecolumn); - oldtexturecolumn_top = toptexturecolumn; + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-textureoffset); + oldtexturecolumn_top = textureoffset; } else if (markceiling && (!rw_ceilingmarked)) // no top wall ceilingclip[rw_x] = topclip; @@ -1369,10 +1396,9 @@ static void R_RenderSegLoop (void) dc_yl = mid; dc_yh = yh; dc_texturemid = rw_bottomtexturemid; - dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_bottomtexturescaley); - dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels; dc_texheight = textureheight[bottomtexture]>>FRACBITS; - colfunc(); + dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, bottomscaley); + drawbottom(R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels, dc_texheight); floorclip[rw_x] = (INT16)mid; } else if (!rw_floormarked) // entirely off bottom of screen @@ -1382,8 +1408,8 @@ static void R_RenderSegLoop (void) floorclip[rw_x] = bottomclip; if (oldtexturecolumn_bottom != -1) - rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-bottomtexturecolumn); - oldtexturecolumn_bottom = bottomtexturecolumn; + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-textureoffset); + oldtexturecolumn_bottom = textureoffset; } else if (markfloor && (!rw_floormarked)) // no bottom wall floorclip[rw_x] = bottomclip; @@ -1407,11 +1433,14 @@ static void R_RenderSegLoop (void) { if (oldtexturecolumn != -1) { - rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); - rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); + INT32 diff = oldtexturecolumn-textureoffset; + if (rw_invmidtexturescalex < 0) + diff = -diff; + rw_midtexturemid += FixedMul(rw_midtextureslide, diff); + rw_midtextureback += FixedMul(rw_midtexturebackslide, diff); } - oldtexturecolumn = texturecolumn; + oldtexturecolumn = textureoffset; } if (invscale) @@ -1505,7 +1534,7 @@ static void R_AllocClippingTables(size_t range) static void R_AllocTextureColumnTables(size_t range) { size_t pos = curtexturecolumntable - texturecolumntable; - size_t need = range * 3; + size_t need = range * 4; if (pos + need < texturecolumntablesize) return; @@ -1526,15 +1555,48 @@ static void R_AllocTextureColumnTables(size_t range) for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) { // Check if it's in range of the tables - if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast) - 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; +#define CHECK(which) \ + if (which + ds->x1 >= oldtable && which + ds->x1 <= oldlast) \ + which = (which - oldtable) + texturecolumntable + + CHECK(ds->maskedtexturecol); + CHECK(ds->maskedtextureheight); + CHECK(ds->thicksidecol); + CHECK(ds->invscale); + +#undef CHECK } } +// +// R_ScaleFromGlobalAngle +// Returns the texture mapping scale for the current line (horizontal span) +// at the given angle. +// rw_distance must be calculated first. +// +// killough 5/2/98: reformatted, cleaned up +// +// note: THIS IS USED ONLY FOR WALLS! +static fixed_t R_ScaleFromGlobalAngle(angle_t visangle) +{ + angle_t anglea = ANGLE_90 + (visangle-viewangle); + angle_t angleb = ANGLE_90 + (visangle-rw_normalangle); + fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT)); + // proff 11/06/98: Changed for high-res + fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT)); + + if (den > num>>16) + { + num = FixedDiv(num, den); + if (num > 64*FRACUNIT) + return 64*FRACUNIT; + if (num < 256) + return 256; + return num; + } + return 64*FRACUNIT; +} + // // R_StoreWallRange // A wall segment will be drawn @@ -1706,11 +1768,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) midtexture = toptexture = bottomtexture = maskedtexture = 0; ds_p->maskedtexturecol = NULL; + ds_p->maskedtextureheight = NULL; ds_p->numthicksides = numthicksides = 0; ds_p->thicksidecol = NULL; ds_p->invscale = NULL; ds_p->tsilheight = 0; + texcoltables = false; + numbackffloors = 0; for (i = 0; i < MAXFFLOORS; i++) @@ -1736,16 +1801,19 @@ void R_StoreWallRange(INT32 start, INT32 stop) angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); if (frontsector->f_slope) - floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + floorfrontslide = R_GetSlopeTextureSlide(frontsector->f_slope, lineangle); if (frontsector->c_slope) - ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + ceilingfrontslide = R_GetSlopeTextureSlide(frontsector->c_slope, lineangle); - if (backsector && backsector->f_slope) - floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + if (backsector) + { + if (backsector->f_slope) + floorbackslide = R_GetSlopeTextureSlide(backsector->f_slope, lineangle); - if (backsector && backsector->c_slope) - ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + if (backsector->c_slope) + ceilingbackslide = R_GetSlopeTextureSlide(backsector->c_slope, lineangle); + } } rw_midtexturescalex = sidedef->scalex_mid; @@ -1761,26 +1829,27 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid; fixed_t texheight = textureheight[midtexture]; + fixed_t scaley = abs(rw_midtexturescaley); if (rw_midtexturescaley > 0) { if (linedef->flags & ML_NOSKEW) { if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight; + rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, scaley) + texheight; else - rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley); + rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, scaley); } else if (linedef->flags & ML_DONTPEGBOTTOM) { - rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight; - rw_midtextureslide = floorfrontslide; + rw_midtexturemid = FixedMul(worldbottom, scaley) + texheight; + rw_midtextureslide = FixedMul(floorfrontslide, scaley); } else { // top of texture at top - rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley); - rw_midtextureslide = ceilingfrontslide; + rw_midtexturemid = FixedMul(worldtop, scaley); + rw_midtextureslide = FixedMul(ceilingfrontslide, scaley); } } else @@ -1791,20 +1860,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (linedef->flags & ML_NOSKEW) { if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley); + rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, scaley); else - rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley) + texheight; + rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, scaley) + texheight; } else if (linedef->flags & ML_DONTPEGBOTTOM) { - rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley); - rw_midtextureslide = floorfrontslide; + rw_midtexturemid = FixedMul(worldbottom, scaley); + rw_midtextureslide = FixedMul(floorfrontslide, scaley); } else { // top of texture at top - rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight; - rw_midtextureslide = ceilingfrontslide; + rw_midtexturemid = FixedMul(worldtop, scaley) + texheight; + rw_midtextureslide = FixedMul(ceilingfrontslide, scaley); } } @@ -2013,15 +2082,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // top of texture at top rw_toptexturemid = worldtop; - rw_toptextureslide = ceilingfrontslide; + rw_toptextureslide = FixedMul(ceilingfrontslide, abs(rw_toptexturescaley)); } else { rw_toptexturemid = worldhigh + texheight; - rw_toptextureslide = ceilingbackslide; + rw_toptextureslide = FixedMul(ceilingbackslide, abs(rw_toptexturescaley)); } - rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley); + rw_toptexturemid = FixedMul(rw_toptexturemid, abs(rw_toptexturescaley)); + rw_toptexturemid += toprowoffset; } // check BOTTOM TEXTURE @@ -2052,24 +2122,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) // bottom of texture at bottom // top of texture at top rw_bottomtexturemid = worldbottom; - rw_bottomtextureslide = floorfrontslide; + rw_bottomtextureslide = FixedMul(floorfrontslide, abs(rw_bottomtexturescaley)); } else { // top of texture at top rw_bottomtexturemid = worldlow; - rw_bottomtextureslide = floorbackslide; + rw_bottomtextureslide = FixedMul(floorbackslide, abs(rw_bottomtexturescaley)); } - rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley); + rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, abs(rw_bottomtexturescaley)); + rw_bottomtexturemid += botrowoffset; } - rw_toptexturemid += toprowoffset; - rw_bottomtexturemid += botrowoffset; - // allocate space for masked texture tables R_AllocTextureColumnTables(rw_stopx - start); + texcoltables = true; + if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) { ffloor_t *rover; @@ -2268,7 +2338,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; curtexturecolumntable += rw_stopx - rw_x; - maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) + ds_p->maskedtextureheight = maskedtextureheight = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; maskedtexture = true; @@ -2310,13 +2381,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - rw_midtexturemid = FixedMul(rw_midtexturemid, rw_midtexturescaley); - rw_midtextureback = FixedMul(rw_midtextureback, rw_midtexturescaley); + rw_midtexturemid = FixedMul(rw_midtexturemid, abs(rw_midtexturescaley)); + rw_midtextureback = FixedMul(rw_midtextureback, abs(rw_midtexturescaley)); + + rw_midtextureslide = FixedMul(rw_midtextureslide, abs(rw_midtexturescaley)); + rw_midtexturebackslide = FixedMul(rw_midtexturebackslide, abs(rw_midtexturescaley)); rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid; rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid; - - maskedtexture = true; } } @@ -2440,7 +2512,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (frontsector->numlights) { dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) + if (dc_numlights > dc_maxlights) { dc_maxlights = dc_numlights; dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); diff --git a/src/r_things.c b/src/r_things.c index d6ef72b9d..2d1e27a59 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -658,12 +658,31 @@ void R_DrawMaskedColumn(column_t *column, unsigned lengthcol) static UINT8 *flippedcol = NULL; static size_t flippedcolsize = 0; +void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void)) +{ + if (!length) + return; + + if (!flippedcolsize || length > flippedcolsize) + { + flippedcolsize = length; + flippedcol = Z_Realloc(flippedcol, length, PU_STATIC, NULL); + } + + dc_source = flippedcol; + + for (UINT8 *s = (UINT8 *)source, *d = flippedcol+length-1; d >= flippedcol; s++) + *d-- = *s; + + drawcolfunc(); +} + void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol) { INT32 topscreen; INT32 bottomscreen; fixed_t basetexturemid = dc_texturemid; - UINT8 *d,*s; + INT32 topdelta; for (unsigned i = 0; i < column->num_posts; i++) { @@ -671,7 +690,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol) if (!post->length) continue; - INT32 topdelta = lengthcol-post->length-post->topdelta; + topdelta = lengthcol-post->length-post->topdelta; topscreen = sprtopscreen + spryscale*topdelta; bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length : sprbotscreen + spryscale*post->length; @@ -698,18 +717,9 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol) if (dc_yl <= dc_yh && dc_yh > 0) { - if (post->length > flippedcolsize) - { - flippedcolsize = post->length; - flippedcol = Z_Realloc(flippedcol, flippedcolsize, PU_STATIC, NULL); - } - - for (s = column->pixels+post->data_offset+post->length, d = flippedcol; d < flippedcol+post->length; --s) - *d++ = *s; - dc_source = flippedcol; dc_texturemid = basetexturemid - (topdelta<pixels + post->data_offset, post->length, colfunc); } } diff --git a/src/r_things.h b/src/r_things.h index 043b454b0..f68d75a83 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -48,6 +48,7 @@ extern fixed_t windowbottom; void R_DrawMaskedColumn(column_t *column, unsigned lengthcol); void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol); +void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void)); // ---------------- // SPRITE RENDERING diff --git a/src/tables.h b/src/tables.h index 2736f03e8..65d7f7243 100644 --- a/src/tables.h +++ b/src/tables.h @@ -81,7 +81,7 @@ extern angle_t tantoangle[SLOPERANGE+1]; // Utility function, called by R_PointToAngle. FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den); -// Only called by R_PointToAngleEx +// Only called by R_PointToAngle64 UINT64 SlopeDivEx(unsigned int num, unsigned int den); // 360 - angle_t(ANGLE_45) = ANGLE_315 From fe2daf907b53162e153e74ae1901d3cd5439a478 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 19 Feb 2024 21:49:22 -0300 Subject: [PATCH 07/18] Make the display of palette index 255 consistent between renderers --- src/hardware/hw_cache.c | 208 +++++++++++++++++++++------------------- src/hardware/hw_defs.h | 2 +- src/hardware/hw_glob.h | 2 +- src/hardware/hw_main.c | 36 +++---- 4 files changed, 134 insertions(+), 114 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index f1f0668be..85bbfd648 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -98,13 +98,11 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm if (position + count >= pblockheight) count = pblockheight - position; - dest = block + (position*blockmodulo); - while (count > 0) + for (dest = block + (position*blockmodulo); count > 0; count--, dest += blockmodulo, yfrac += yfracstep) { - count--; - texel = source[yfrac>>FRACBITS]; alpha = 0xFF; + // Make pixel transparent if chroma keyed if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) alpha = 0x00; @@ -115,11 +113,20 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm switch (bpp) { case 2: + { + texelu16 = *((UINT16*)dest); if ((originPatch != NULL) && (originPatch->style != AST_COPY)) - texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); + { + if (originPatch->style == AST_TRANSLUCENT && originPatch->alpha < ASTTextureBlendingThreshold[0]) + continue; + if (!(texelu16 & 0xFF00) && originPatch->alpha <= ASTTextureBlendingThreshold[1]) + continue; + texel = ASTBlendPaletteIndexes(texelu16 & 0xFF, texel, originPatch->style, originPatch->alpha); + } texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; + } case 3: colortemp = palette[texel]; if ((originPatch != NULL) && (originPatch->style != AST_COPY)) @@ -149,9 +156,6 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm *dest = texel; break; } - - dest += blockmodulo; - yfrac += yfracstep; } } } @@ -202,13 +206,11 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, if (position + count >= pblockheight) count = pblockheight - position; - dest = block + (position*blockmodulo); - while (count > 0) + for (dest = block + (position*blockmodulo); count > 0; count--, dest += blockmodulo, yfrac -= yfracstep) { - count--; - texel = source[yfrac>>FRACBITS]; alpha = 0xFF; + // Make pixel transparent if chroma keyed if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) alpha = 0x00; @@ -219,8 +221,15 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, switch (bpp) { case 2: + texelu16 = *((UINT16*)dest); if ((originPatch != NULL) && (originPatch->style != AST_COPY)) - texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); + { + if (originPatch->style == AST_TRANSLUCENT && originPatch->alpha < ASTTextureBlendingThreshold[0]) + continue; + if (!(texelu16 & 0xFF00) && originPatch->alpha <= ASTTextureBlendingThreshold[1]) + continue; + texel = ASTBlendPaletteIndexes(texelu16 & 0xFF, texel, originPatch->style, originPatch->alpha); + } texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; @@ -253,9 +262,6 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, *dest = texel; break; } - - dest += blockmodulo; - yfrac -= yfracstep; } } } @@ -433,7 +439,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap) // Create a composite texture from patches, adapt the texture size to a power of 2 // height and width for the hardware texture cache. // -static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) +static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t *mipmap) { UINT8 *block; texture_t *texture; @@ -441,57 +447,19 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) INT32 blockwidth, blockheight, blocksize; INT32 i; - boolean skyspecial = false; //poor hack for Legacy large skies.. - - RGBA_t *palette; - palette = HWR_GetTexturePalette(); texture = textures[texnum]; - // hack the Legacy skies.. - if (texture->name[0] == 'S' && - texture->name[1] == 'K' && - texture->name[2] == 'Y' && - (texture->name[4] == 0 || - texture->name[5] == 0) - ) - { - skyspecial = true; - grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky - } - else - grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; - - grtex->mipmap.width = (UINT16)texture->width; - grtex->mipmap.height = (UINT16)texture->height; - if (skyspecial) - grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ... - else - grtex->mipmap.format = textureformat; + mipmap->flags = TF_WRAPXY; + mipmap->width = (UINT16)texture->width; + mipmap->height = (UINT16)texture->height; + mipmap->format = textureformat; blockwidth = texture->width; blockheight = texture->height; blocksize = (blockwidth * blockheight); block = MakeBlock(&grtex->mipmap); - if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading) - { - INT32 j; - RGBA_t col; - - col = palette[HWR_PATCHES_CHROMAKEY_COLORINDEX]; - for (j = 0; j < blockheight; j++) - { - for (i = 0; i < blockwidth; i++) - { - block[4*(j*blockwidth+i)+0] = col.s.red; - block[4*(j*blockwidth+i)+1] = col.s.green; - block[4*(j*blockwidth+i)+2] = col.s.blue; - block[4*(j*blockwidth+i)+3] = 0xff; - } - } - } - // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { @@ -526,13 +494,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) Patch_Free(realpatch); } //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( - if (format2bpp(grtex->mipmap.format)==4) + if (format2bpp(mipmap->format)==4) { for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp { if (block[i] == 0) { - grtex->mipmap.flags |= TF_TRANSPARENT; + mipmap->flags |= TF_TRANSPARENT; break; } } @@ -661,8 +629,6 @@ void HWR_FreeTextureColormaps(patch_t *patch) Z_Free(next->data); if (next->colormap) Z_Free(next->colormap); - next->data = NULL; - next->colormap = NULL; HWD.pfnDeleteTexture(next); // Free the old colormap mipmap from memory. @@ -714,12 +680,25 @@ void HWR_InitMapTextures(void) gl_maptexturesloaded = false; } +static void DeleteTextureMipmap(GLMipmap_t *grMipmap) +{ + HWD.pfnDeleteTexture(grMipmap); + + // Chroma-keyed textures do not own their texture data, so do not free it + if (!(grMipmap->flags & TF_CHROMAKEYED)) + Z_Free(grMipmap->data); +} + static void FreeMapTexture(GLMapTexture_t *tex) { - HWD.pfnDeleteTexture(&tex->mipmap); - if (tex->mipmap.data) - Z_Free(tex->mipmap.data); - tex->mipmap.data = NULL; + if (tex->mipmap.nextcolormap) + { + DeleteTextureMipmap(tex->mipmap.nextcolormap); + free(tex->mipmap.nextcolormap); + tex->mipmap.nextcolormap = NULL; + } + + DeleteTextureMipmap(&tex->mipmap); } void HWR_FreeMapTextures(void) @@ -762,41 +741,43 @@ void HWR_LoadMapTextures(size_t pnumtextures) // -------------------------------------------------------------------------- // Make sure texture is downloaded and set it as the source // -------------------------------------------------------------------------- +static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap) +{ + // Generate texture if missing from the cache + if (!mipmap->data && !mipmap->downloaded) + HWR_GenerateTexture(tex, grtex, mipmap); + + // If hardware does not have the texture, then call pfnSetTexture to upload it + if (!mipmap->downloaded) + HWD.pfnSetTexture(mipmap); + HWR_SetCurrentTexture(mipmap); + + // The system-memory data can be purged now. + Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED); +} + GLMapTexture_t *HWR_GetTexture(INT32 tex) { - GLMapTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gl_numtextures) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif - // Every texture in memory, stored in the - // hardware renderer's bit depth format. Wow! - grtex = &gl_textures[tex]; + GLMapTexture_t *grtex = &gl_textures[tex]; - // Generate texture if missing from the cache - if (!grtex->mipmap.data && !grtex->mipmap.downloaded) - HWR_GenerateTexture(tex, grtex); - - // If hardware does not have the texture, then call pfnSetTexture to upload it - if (!grtex->mipmap.downloaded) - HWD.pfnSetTexture(&grtex->mipmap); - HWR_SetCurrentTexture(&grtex->mipmap); - - // The system-memory data can be purged now. - Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED); + GetMapTexture(tex, grtex, &grtex->mipmap); return grtex; } -static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) +static void HWR_CacheRawFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) { size_t size = W_LumpLength(flatlumpnum); UINT16 pflatsize = R_GetFlatSize(size); // setup the texture info grMipmap->format = GL_TEXFMT_P_8; - grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; + grMipmap->flags = TF_WRAPXY; grMipmap->width = pflatsize; grMipmap->height = pflatsize; @@ -817,7 +798,7 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum) patch = HWR_GetCachedGLPatch(flatlumpnum); grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap; if (!grmip->downloaded && !grmip->data) - HWR_CacheFlat(grmip, flatlumpnum); + HWR_CacheRawFlat(grmip, flatlumpnum); // If hardware does not have the texture, then call pfnSetTexture to upload it if (!grmip->downloaded) @@ -828,7 +809,16 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum) Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); } -void HWR_GetLevelFlat(levelflat_t *levelflat) +static void MakeLevelFlatMipmap(GLMipmap_t *grMipmap, INT32 texturenum, UINT16 flags) +{ + grMipmap->format = GL_TEXFMT_P_8; + grMipmap->flags = flags; + + grMipmap->width = (UINT16)textures[texturenum]->width; + grMipmap->height = (UINT16)textures[texturenum]->height; +} + +void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed) { if (levelflat->type == LEVELFLAT_NONE || levelflat->texture_id < 0) { @@ -839,24 +829,50 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) INT32 texturenum = texturetranslation[levelflat->texture_id]; GLMapTexture_t *grtex = &gl_flats[texturenum]; + GLMipmap_t *grMipmap = &grtex->mipmap; + GLMipmap_t *originalMipmap = grMipmap; - if (!grMipmap->data && !grMipmap->downloaded) + if (!originalMipmap->downloaded) + MakeLevelFlatMipmap(originalMipmap, texturenum, TF_WRAPXY); + + if (!originalMipmap->data) { - grMipmap->format = GL_TEXFMT_P_8; - grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; + size_t size = originalMipmap->width * originalMipmap->height; + memcpy(Z_Malloc(size, PU_HWRCACHE, &originalMipmap->data), R_GetFlatForTexture(texturenum), size); + } - grMipmap->width = (UINT16)textures[texturenum]->width; - grMipmap->height = (UINT16)textures[texturenum]->height; + // If chroma-keyed, create or use a different mipmap for the variant + if (chromakeyed) + { + if (!originalMipmap->data) + { + HWR_SetCurrentTexture(NULL); + return; + } - size_t size = grMipmap->width * grMipmap->height; - memcpy(Z_Malloc(size, PU_HWRCACHE, &grMipmap->data), R_GetFlatForTexture(texturenum), size); + // Allocate it if it wasn't already + if (!originalMipmap->nextcolormap) + { + GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap)); + if (newMipmap == NULL) + I_Error("%s: Out of memory", "HWR_GetLevelFlat"); + MakeLevelFlatMipmap(newMipmap, texturenum, TF_WRAPXY | TF_CHROMAKEYED); + originalMipmap->nextcolormap = newMipmap; + } + + // Upload and bind the variant texture instead of the original one + grMipmap = originalMipmap->nextcolormap; + + // Use the original texture's pixel data + // It can just be a pointer to it, since the r_opengl backend deals with the pixels + // that are supposed to be transparent. + grMipmap->data = originalMipmap->data; } if (!grMipmap->downloaded) - HWD.pfnSetTexture(&grtex->mipmap); - - HWR_SetCurrentTexture(&grtex->mipmap); + HWD.pfnSetTexture(grMipmap); + HWR_SetCurrentTexture(grMipmap); Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED); } diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 2d55eef2d..7d06ceb60 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -246,7 +246,7 @@ enum ETextureFlags TF_WRAPX = 0x00000001, // wrap around X TF_WRAPY = 0x00000002, // wrap around Y TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy - TF_CHROMAKEYED = 0x00000010, + TF_CHROMAKEYED = 0x00000010, // Used only for flats with pixels that have palette index 255 TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 }; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 094d356d5..e4c8a359e 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -122,7 +122,7 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum); patch_t *HWR_GetPic(lumpnum_t lumpnum); GLMapTexture_t *HWR_GetTexture(INT32 tex); -void HWR_GetLevelFlat(levelflat_t *levelflat); +void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed); void HWR_GetRawFlat(lumpnum_t flatlumpnum); void HWR_FreeTexture(patch_t *patch); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1cfffca54..df2829af6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -69,7 +69,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); #endif static void HWR_ProjectBoundingBox(mobj_t *thing); -void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); +void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, boolean chromakeyed, extracolormap_t *planecolormap); void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); @@ -2875,7 +2875,7 @@ static void HWR_AddPolyObjectPlanes(void) } else { - HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic]); + HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic], false); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic], polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap)); @@ -2898,7 +2898,7 @@ static void HWR_AddPolyObjectPlanes(void) } else { - HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic]); + HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic], false); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->ceilingpic], polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap)); @@ -3029,7 +3029,7 @@ static void HWR_Subsector(size_t num) { if (sub->validcount != validcount) { - HWR_GetLevelFlat(&levelflats[gl_frontsector->floorpic]); + HWR_GetLevelFlat(&levelflats[gl_frontsector->floorpic], false); HWR_RenderPlane(sub, &extrasubsectors[num], false, // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gl_frontsector->floorheight, @@ -3051,7 +3051,7 @@ static void HWR_Subsector(size_t num) { if (sub->validcount != validcount) { - HWR_GetLevelFlat(&levelflats[gl_frontsector->ceilingpic]); + HWR_GetLevelFlat(&levelflats[gl_frontsector->ceilingpic], false); HWR_RenderPlane(sub, &extrasubsectors[num], true, // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gl_frontsector->ceilingheight, @@ -3118,7 +3118,7 @@ static void HWR_Subsector(size_t num) *rover->bottomheight, *gl_frontsector->lightlist[light].lightlevel, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, - true, rover->master->frontsector->extra_colormap); + true, false, rover->master->frontsector->extra_colormap); } else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) // SoM: Flags are more efficient { @@ -3131,11 +3131,11 @@ static void HWR_Subsector(size_t num) *gl_frontsector->lightlist[light].lightlevel, max(0, min(rover->alpha, 255)), rover->master->frontsector, HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), - false, *gl_frontsector->lightlist[light].extra_colormap); + false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap); } else { - HWR_GetLevelFlat(&levelflats[*rover->bottompic]); + HWR_GetLevelFlat(&levelflats[*rover->bottompic], rover->fofflags & FOF_SPLAT); light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < bottomCullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); @@ -3163,7 +3163,7 @@ static void HWR_Subsector(size_t num) *rover->topheight, *gl_frontsector->lightlist[light].lightlevel, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, - true, rover->master->frontsector->extra_colormap); + true, false, rover->master->frontsector->extra_colormap); } else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) { @@ -3176,11 +3176,11 @@ static void HWR_Subsector(size_t num) *gl_frontsector->lightlist[light].lightlevel, max(0, min(rover->alpha, 255)), rover->master->frontsector, HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), - false, *gl_frontsector->lightlist[light].extra_colormap); + false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap); } else { - HWR_GetLevelFlat(&levelflats[*rover->toppic]); + HWR_GetLevelFlat(&levelflats[*rover->toppic], rover->fofflags & FOF_SPLAT); light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < topCullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); @@ -4620,6 +4620,7 @@ typedef struct sector_t *FOFSector; FBITFIELD blend; boolean fogplane; + boolean chromakeyed; extracolormap_t *planecolormap; INT32 drawcount; } planeinfo_t; @@ -4661,7 +4662,7 @@ static INT32 drawcount = 0; #define MAX_TRANSPARENTFLOOR 512 // This will likely turn into a copy of HWR_Add3DWater and replace it. -void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) +void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, boolean chromakeyed, extracolormap_t *planecolormap) { static size_t allocedplanes = 0; @@ -4684,6 +4685,7 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo planeinfo[numplanes].FOFSector = FOFSector; planeinfo[numplanes].blend = blend; planeinfo[numplanes].fogplane = fogplane; + planeinfo[numplanes].chromakeyed = chromakeyed; planeinfo[numplanes].planecolormap = planecolormap; planeinfo[numplanes].drawcount = drawcount++; @@ -4850,7 +4852,7 @@ static void HWR_CreateDrawNodes(void) gl_frontsector = NULL; if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) - HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat); + HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->chromakeyed); HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap); } @@ -4859,9 +4861,11 @@ static void HWR_CreateDrawNodes(void) // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. gl_frontsector = NULL; + polyobj_t *po = sortnode[sortindex[i]].polyplane->polysector; + if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture)) - HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat); - HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, + HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat, po->flags & POF_SPLAT); + HWR_RenderPolyObjectPlane(po, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); } else if (sortnode[sortindex[i]].wall) @@ -6484,7 +6488,7 @@ static void HWR_TogglePaletteRendering(void) // The textures will still be converted to RGBA by r_opengl. // This however makes hw_cache use paletted blending for composite textures! // (patchformat is not touched) - textureformat = GL_TEXFMT_P_8; + textureformat = GL_TEXFMT_AP_88; HWR_SetMapPalette(); HWR_SetPalette(pLocalPalette); From 467cc59c64e7cc5f066b06fac1992f51a89bd0be Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 19 Feb 2024 22:55:45 -0300 Subject: [PATCH 08/18] Only I_Error in HWR_GetTexture with PARANOIA --- src/hardware/hw_cache.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 85bbfd648..d244ec0f6 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -758,10 +758,15 @@ static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap) GLMapTexture_t *HWR_GetTexture(INT32 tex) { + if (tex < 0 || tex >= (signed)gl_numtextures) + { #ifdef PARANOIA - if ((unsigned)tex >= gl_numtextures) - I_Error("HWR_GetTexture: tex >= numtextures\n"); + I_Error("HWR_GetTexture: Invalid texture ID %d", tex); +#else + HWR_SetCurrentTexture(NULL); + return; #endif + } GLMapTexture_t *grtex = &gl_textures[tex]; From 0292e0e1f6d7f75dc98442438714a8601295a6b6 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 19 Feb 2024 23:02:44 -0300 Subject: [PATCH 09/18] Fix build error --- src/hardware/hw_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index d244ec0f6..f51a6e863 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -763,8 +763,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex) #ifdef PARANOIA I_Error("HWR_GetTexture: Invalid texture ID %d", tex); #else - HWR_SetCurrentTexture(NULL); - return; + tex = 0; #endif } From 18e7f0ee2d6146dd94efccd954b268a07b2ac43e Mon Sep 17 00:00:00 2001 From: 256nil Date: Tue, 20 Feb 2024 18:08:57 +0200 Subject: [PATCH 10/18] Fix #1188 --- src/console.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/console.c b/src/console.c index 0d296ca74..b8571543a 100644 --- a/src/console.c +++ b/src/console.c @@ -882,12 +882,6 @@ static void CON_InputDelSelection(void) Lock_state(); - if (!input_cur) - { - Unlock_state(); - return; - } - if (input_cur > input_sel) { start = input_sel; From 978a6b27172c9bd9d9593fc406f7ecf2ce6dd373 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 20 Feb 2024 23:22:43 -0300 Subject: [PATCH 11/18] Fix typos in R_RenderPortalHorizonLine --- src/r_bsp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 918dc40b0..d606d7a27 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1382,10 +1382,9 @@ void R_RenderPortalHorizonLine(sector_t *sector) || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) { - ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, - ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingxscale, frontsector->ceilingyscale, - frontsector->ceilingyoffset, frontsector->ceilingangle, - ceilingcolormap, NULL, NULL, NULL, NULL); + ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, + frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingxscale, frontsector->ceilingyscale, + frontsector->ceilingangle, ceilingcolormap, NULL, NULL, NULL, NULL); } else ceilingplane = NULL; From 90958614f3c1519493ef9d4ccd14b925cea910a3 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 24 Feb 2024 15:41:36 +0100 Subject: [PATCH 12/18] Shield button touchups --- src/deh_lua.c | 15 +++- src/deh_tables.c | 6 ++ src/g_demo.c | 6 +- src/g_game.c | 55 +++++++----- src/g_game.h | 5 +- src/g_input.c | 1 - src/lua_baselib.c | 18 +++- src/m_menu.c | 38 ++++---- src/netcode/d_netcmd.c | 2 + src/p_local.h | 11 ++- src/p_user.c | 192 ++++++++++++++++++++++++----------------- src/st_stuff.c | 6 +- src/y_inter.c | 4 +- 13 files changed, 228 insertions(+), 131 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 3600c3554..c056db82a 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -11,6 +11,7 @@ /// \brief Lua SOC library #include "deh_lua.h" +#include "g_input.h" // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. @@ -596,12 +597,20 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) return luaL_error(L, "translation '%s' could not be found.\n", word); } - // TODO: 2.3: Delete this alias - if (fastcmp(word, "BT_USE")) + // TODO: 2.3: Delete these aliases + else if (fastcmp(word, "BT_USE")) { CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); return 1; - } + } + else if (fastcmp(word, "GC_WEPSLOT8") || fastcmp(word, "GC_WEPSLOT9") || fastcmp(word, "GC_WEPSLOT10")) + { + // Using GC_WEPSLOT7 isn't accurate, but ensures that "if x >= GC_WEPSLOT1 and x <= GC_WEPSLOT10" keeps the intended effect + CacheAndPushConstant(L, word, (lua_Integer)GC_WEPSLOT7); + if (!mathlib) + LUA_Deprecated(L, "GC_WEPSLOT8\"-\"GC_WEPSLOT10", "GC_WEPSLOT1\"-\"GC_WEPSLOT7"); + return 1; + } for (i = 0; INT_CONST[i].n; i++) if (fastcmp(word,INT_CONST[i].n)) { diff --git a/src/deh_tables.c b/src/deh_tables.c index fa86518e2..2ccf80e14 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5315,6 +5315,11 @@ struct int_const_s const INT_CONST[] = { //// Masks {"DMG_CANHURTSELF",DMG_CANHURTSELF}, {"DMG_DEATHMASK",DMG_DEATHMASK}, + // For P_SuperReady + {"SUPERREADY_CLASSIC",SUPERREADY_CLASSIC}, + {"SUPERREADY_TRANSFORM",SUPERREADY_TRANSFORM}, + {"SUPERREADY_DETRANSFORM",SUPERREADY_DETRANSFORM}, + {"NUMSUPERREADY",NUMSUPERREADY}, // Intermission types {"int_none",int_none}, @@ -5737,6 +5742,7 @@ struct int_const_s const INT_CONST[] = { {"JA_DIGITAL",JA_DIGITAL}, {"JA_JUMP",JA_JUMP}, {"JA_SPIN",JA_SPIN}, + {"JA_SHIELD",JA_SHIELD}, {"JA_FIRE",JA_FIRE}, {"JA_FIRENORMAL",JA_FIRENORMAL}, {"JOYAXISRANGE",JOYAXISRANGE}, diff --git a/src/g_demo.c b/src/g_demo.c index f64f34168..7af9c5949 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -98,7 +98,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x0011 +#define DEMOVERSION 0x0012 #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -183,7 +183,11 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) if (ziptic & ZT_ANGLE) oldcmd.angleturn = READINT16(demo_p); if (ziptic & ZT_BUTTONS) + { oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); + if (demoversion < 0x0012 && oldcmd.buttons & BT_SPIN) + oldcmd.buttons |= BT_SHIELD; // Copy BT_SPIN to BT_SHIELD for pre-Shield-button demos + } if (ziptic & ZT_AIMING) oldcmd.aiming = READINT16(demo_p); if (ziptic & ZT_LATENCY) diff --git a/src/g_game.c b/src/g_game.c index 6a99381e7..6fff76ca8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -403,27 +403,29 @@ consvar_t cv_cam_lockonboss[2] = { CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL), }; -consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); -consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_shieldaxis = CVAR_INIT ("joyaxis_shield", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); -consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); -consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_shieldaxis2 = CVAR_INIT ("joyaxis2_shield", "None", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); +consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); player_t *seenplayer; // player we're aiming at right now @@ -894,6 +896,9 @@ INT32 JoyAxis(joyaxis_e axissel) case JA_SPIN: axisval = cv_spinaxis.value; break; + case JA_SHIELD: + axisval = cv_shieldaxis.value; + break; case JA_FIRE: axisval = cv_fireaxis.value; break; @@ -967,6 +972,9 @@ INT32 Joy2Axis(joyaxis_e axissel) case JA_SPIN: axisval = cv_spinaxis2.value; break; + case JA_SHIELD: + axisval = cv_shieldaxis2.value; + break; case JA_FIRE: axisval = cv_fireaxis2.value; break; @@ -1334,8 +1342,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV)) cmd->buttons |= BT_WEAPONPREV; // Previous Weapon -#if NUM_WEAPONS > 10 -"Add extra inputs to g_input.h/gamecontrols_e" +#if NUM_WEAPONS > 7 +"Add extra inputs to g_input.h/gamecontrols_e, and fix conflicts in d_ticcmd.h/ticcmd_t/buttons" #endif //use the three avaliable bits to determine the weapon. cmd->buttons &= ~BT_WEAPONMASK; @@ -1361,7 +1369,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->buttons |= BT_TOSSFLAG; // Shield button - if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD)) + axis = PlayerJoyAxis(ssplayer, JA_SHIELD); + if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0)) cmd->buttons |= BT_SHIELD; // Lua scriptable buttons diff --git a/src/g_game.h b/src/g_game.h index 80a815f02..0d5fc7e37 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -71,8 +71,8 @@ typedef enum { #define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) extern consvar_t cv_autobrake, cv_autobrake2; -extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; -extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; +extern consvar_t cv_sideaxis, cv_turnaxis, cv_moveaxis, cv_lookaxis, cv_jumpaxis, cv_spinaxis, cv_shieldaxis, cv_fireaxis, cv_firenaxis, cv_deadzone, cv_digitaldeadzone; +extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_shieldaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls @@ -100,6 +100,7 @@ typedef enum JA_JUMP = JA_DIGITAL, JA_SPIN, + JA_SHIELD, JA_FIRE, JA_FIRENORMAL, } joyaxis_e; diff --git a/src/g_input.c b/src/g_input.c index 3f1be37ba..5fa642f1d 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1001,7 +1001,6 @@ static void setcontrol(INT32 (*gc)[2]) // TODO: 2.3: Delete the "use" alias namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin"; - for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]); numctrl++) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 680c6a2c3..a5162837e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1712,12 +1712,14 @@ static int lib_pResetCamera(lua_State *L) static int lib_pSuperReady(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - boolean transform = (boolean)lua_opttrueboolean(L, 2); + superready_t type = luaL_optinteger(L, 2, SUPERREADY_CLASSIC); //HUDSAFE INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushboolean(L, P_SuperReady(player, transform)); + if (type < 0 || type >= NUMSUPERREADY) + return luaL_error(L, "superready type %d out of range (0 - %d)", type, NUMSUPERREADY-1); + lua_pushboolean(L, P_SuperReady(player, type)); return 1; } @@ -2497,6 +2499,17 @@ static int lib_pDoSuperTransformation(lua_State *L) return 0; } +static int lib_pDoSuperDetransformation(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoSuperDetransformation(player); + return 0; +} + static int lib_pExplodeMissile(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -4450,6 +4463,7 @@ static luaL_Reg lib[] = { {"P_VectorInstaThrust",lib_pVectorInstaThrust}, {"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_DoSuperTransformation",lib_pDoSuperTransformation}, + {"P_DoSuperDetransformation",lib_pDoSuperDetransformation}, {"P_ExplodeMissile",lib_pExplodeMissile}, {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, {"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor}, diff --git a/src/m_menu.c b/src/m_menu.c index 3c6ef0fe3..cf062c65c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1068,9 +1068,9 @@ static menuitem_t OP_ChangeControlsMenu[] = {IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, GC_BACKWARD }, {IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, GC_STRAFELEFT }, {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT }, - {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, - {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, - {IT_CALL | IT_STRING2, NULL, "Shield", M_ChangeControl, GC_SHIELD }, + {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, + {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, + {IT_CALL | IT_STRING2, NULL, "Shield Ability", M_ChangeControl, GC_SHIELD }, {IT_HEADER, NULL, "Camera", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP }, @@ -1119,13 +1119,15 @@ static menuitem_t OP_ChangeControlsMenu[] = static menuitem_t OP_Joystick1Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup1PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 30}, - {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 40}, - {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 50}, - {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 60}, - {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis , 70}, - {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis , 80}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup1PJoystickMenu, 0}, + + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 20}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 30}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 50}, + {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis , 60}, + {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis , 70}, + {IT_STRING | IT_CVAR, NULL, "Shield Axis" , &cv_shieldaxis , 80}, {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis , 90}, {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis ,100}, @@ -1137,13 +1139,15 @@ static menuitem_t OP_Joystick1Menu[] = static menuitem_t OP_Joystick2Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup2PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 30}, - {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 40}, - {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 50}, - {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 60}, - {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis2 , 70}, - {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis2 , 80}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup2PJoystickMenu, 0}, + + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 20}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 30}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 50}, + {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis2 , 60}, + {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis2 , 70}, + {IT_STRING | IT_CVAR, NULL, "Shield Axis" , &cv_shieldaxis2 , 80}, {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis2 , 90}, {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis2 ,100}, diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 6bdcaa650..96a6bcea7 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -805,6 +805,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_jumpaxis2); CV_RegisterVar(&cv_spinaxis); CV_RegisterVar(&cv_spinaxis2); + CV_RegisterVar(&cv_shieldaxis); + CV_RegisterVar(&cv_shieldaxis2); CV_RegisterVar(&cv_fireaxis); CV_RegisterVar(&cv_fireaxis2); CV_RegisterVar(&cv_firenaxis); diff --git a/src/p_local.h b/src/p_local.h index 9644e7a24..da8956ae1 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -113,6 +113,14 @@ typedef struct camera_s fixed_t momx, momy, momz; } camera_t; +typedef enum +{ + SUPERREADY_CLASSIC, // Two-button play mode, when Spin and Shield are bound to the same button (pressed on the same tic) + SUPERREADY_TRANSFORM, + SUPERREADY_DETRANSFORM, + NUMSUPERREADY +} superready_t; + extern camera_t camera, camera2; extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height; extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_turnmultiplier, cv_cam_orbit, cv_cam_adjust; @@ -203,7 +211,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user -boolean P_SuperReady(player_t *player, boolean transform); +boolean P_SuperReady(player_t *player, superready_t type); void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip); void P_DoSpinDashDust(player_t *player); #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) @@ -552,6 +560,7 @@ void P_ThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed_t ya, fixed_t yb, fixed_t yc, fixed_t za, fixed_t zb, fixed_t zc, fixed_t momentum, mobj_t *mo); void P_DoSuperTransformation(player_t *player, boolean giverings); +void P_DoSuperDetransformation(player_t *player); void P_ExplodeMissile(mobj_t *mo); void P_CheckGravity(mobj_t *mo, boolean affect); void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); diff --git a/src/p_user.c b/src/p_user.c index 9d0eed288..30650b5bb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1378,7 +1378,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // P_DoSuperDetransformation // // Detransform into regular Sonic! -static void P_DoSuperDetransformation(player_t *player) +void P_DoSuperDetransformation(player_t *player) { player->powers[pw_emeralds] = 0; // lost the power stones P_SpawnGhostMobj(player->mo); @@ -4189,16 +4189,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) I_Assert(player != NULL); I_Assert(!P_MobjWasRemoved(player->mo)); - - // Toss a flag - if (cmd->buttons & BT_TOSSFLAG && G_GametypeHasTeams() - && !(player->powers[pw_super]) && !(player->tossdelay)) - { - if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - P_PlayerEmeraldBurst(player, true); // Toss emeralds - else - P_PlayerFlagBurst(player, true); - } if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL))) { @@ -4208,7 +4198,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) return; } - if (player->pflags & PF_ATTACKDOWN || player->climbing) + if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT))) return; // Fire a fireball if we have the Fire Flower powerup! @@ -4224,7 +4214,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) } // No ringslinging outside of ringslinger! - if (!G_RingSlingerGametype() || player->weapondelay || (G_TagGametype() && !(player->pflags & PF_TAGIT))) + if (!G_RingSlingerGametype() || player->weapondelay) return; player->pflags |= PF_ATTACKDOWN; @@ -4441,25 +4431,54 @@ static void P_DoSuperStuff(player_t *player) // // Returns true if player is ready to transform or detransform // -boolean P_SuperReady(player_t *player, boolean transform) +boolean P_SuperReady(player_t *player, superready_t type) { - if (!transform && - (player->powers[pw_super] < TICRATE*3/2 - || !G_CoopGametype())) // No turning back in competitive! - return false; - else if (transform - && (player->powers[pw_super] - || !ALL7EMERALDS(emeralds) - || !(player->rings >= 50))) - return false; - + switch (type) // Transformation-type-specific checks + { + case SUPERREADY_CLASSIC: + // Pressed Spin and Shield on the same tic? Then you've probably bound them to the same button, + // so let's match the earlier Spin-only button behaviour to still support two-button play + if (!player->powers[pw_super] + && !player->powers[pw_invulnerability] + && !player->powers[pw_tailsfly] + && (player->charflags & SF_SUPER) + && (player->pflags & PF_JUMPED) + && !(player->powers[pw_shield] & SH_NOSTACK) + && !(maptol & TOL_NIGHTS) + && ALL7EMERALDS(emeralds) + && (player->rings >= 50)) + return true; + else + return false; + break; + + case SUPERREADY_TRANSFORM: + // Turning Super by pressing Shield? + if (player->powers[pw_super] + || !ALL7EMERALDS(emeralds) + || !(player->rings >= 50)) + return false; + break; + + case SUPERREADY_DETRANSFORM: + // Reverting from Super by pressing Shield? + if ((player->powers[pw_super] < TICRATE*3/2) // No spamming the transformation sound! + || !G_CoopGametype()) // No turning back in competitive! + return false; + break; + + default: // "type" is an enum, so having a case for every enum value pleases the compiler + break; + } + + // These checks apply to both SUPERREADY_TRANSFORM and SUPERREADY_DETRANSFORM if (player->mo && !player->powers[pw_tailsfly] && !player->powers[pw_carry] && (player->charflags & SF_SUPER) && !P_PlayerInPain(player) && !player->climbing - && !(player->pflags & (PF_FULLSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) + && !(player->pflags & (PF_JUMPSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) && ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE || player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH)))) && !(maptol & TOL_NIGHTS)) @@ -5281,7 +5300,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock // // Handles player jumping // -static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) +static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhack) { mobj_t *lockonthok = NULL, *visual = NULL; @@ -5314,45 +5333,52 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) ; else if (P_PlayerShieldThink(player, cmd, lockonthok, visual)) ; - else if ((cmd->buttons & BT_SPIN) && !LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) + else if (cmd->buttons & BT_SPIN) { - switch (player->charability) + if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player, SUPERREADY_CLASSIC)) { - case CA_THOK: - if (player->powers[pw_super]) // Super Sonic float - { - if ((player->speed > 5*player->mo->scale) // FixedMul(5<mo->scale), but scale is FRACUNIT-based - && (P_MobjFlip(player->mo)*player->mo->momz <= 0)) - { - if (player->panim != PA_RUN && player->panim != PA_WALK) - { - if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) - P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN); - else - P_SetMobjState(player->mo, S_PLAY_FLOAT); - } - - player->mo->momz = 0; - player->pflags &= ~(PF_STARTJUMP|PF_SPINNING); - player->secondjump = 1; - } - } - break; - case CA_TELEKINESIS: - if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY)) - { - P_Telekinesis(player, - -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) - FixedMul(384*FRACUNIT, player->mo->scale)); - } - break; - case CA_TWINSPIN: - if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY)) - P_DoTwinSpin(player); - break; - default: - break; + // If you're using two-button play, can turn Super and aren't already, + // and you don't have a shield, then turn Super! + P_DoSuperTransformation(player, false); } + else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) + switch (player->charability) + { + case CA_THOK: + if (player->powers[pw_super]) // Super Sonic float + { + if ((player->speed > 5*player->mo->scale) // FixedMul(5<mo->scale), but scale is FRACUNIT-based + && (P_MobjFlip(player->mo)*player->mo->momz <= 0)) + { + if (player->panim != PA_RUN && player->panim != PA_WALK) + { + if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) + P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN); + else + P_SetMobjState(player->mo, S_PLAY_FLOAT); + } + + player->mo->momz = 0; + player->pflags &= ~(PF_STARTJUMP|PF_SPINNING); + player->secondjump = 1; + } + } + break; + case CA_TELEKINESIS: + if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY)) + { + P_Telekinesis(player, + -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) + FixedMul(384*FRACUNIT, player->mo->scale)); + } + break; + case CA_TWINSPIN: + if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY)) + P_DoTwinSpin(player); + break; + default: + break; + } } } @@ -8074,6 +8100,7 @@ void P_MovePlayer(player_t *player) { ticcmd_t *cmd; INT32 i; + boolean spinshieldhack = false; // Hack: Is Spin and Shield bound to the same button (pressed on the same tic)? fixed_t runspd; @@ -8696,10 +8723,13 @@ void P_MovePlayer(player_t *player) && !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) P_ElementalFire(player, false); + if ((cmd->buttons & (BT_SPIN|BT_SHIELD)) == (BT_SPIN|BT_SHIELD) && !(player->pflags & (PF_SPINDOWN|PF_SHIELDDOWN))) + spinshieldhack = true; // Spin and Shield is bound to the same button (pressed on the same tic), so enable two-button play (Jump and Spin+Shield) + P_DoSpinAbility(player, cmd); // jumping - P_DoJumpStuff(player, cmd); + P_DoJumpStuff(player, cmd, spinshieldhack); // If you're not spinning, you'd better not be spindashing! if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE) @@ -8777,30 +8807,32 @@ void P_MovePlayer(player_t *player) if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) && player->panim == PA_IDLE && !(player->powers[pw_carry])) P_DoTeeter(player); + + // Toss a flag + if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay)) + { + if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) + P_PlayerEmeraldBurst(player, true); // Toss emeralds + else + P_PlayerFlagBurst(player, true); + } // Check for fire and shield buttons - if (!player->exiting && !(player->pflags & PF_STASIS)) + if (!player->exiting) { - // Check for fire buttons P_DoFiring(player, cmd); - - // Release the shield button - if (!(cmd->buttons & BT_SHIELD)) - player->pflags &= ~PF_SHIELDDOWN; - + // Shield button behavior // Check P_PlayerShieldThink for actual shields! - else if (!(player->pflags & PF_SHIELDDOWN)) + if ((cmd->buttons & BT_SHIELD) && !(player->pflags & PF_SHIELDDOWN) && !spinshieldhack) { // Transform into super if we can! - if (P_SuperReady(player, true)) + if (P_SuperReady(player, SUPERREADY_TRANSFORM)) P_DoSuperTransformation(player, false); - + // Detransform from super if we can! - else if (P_SuperReady(player, false)) + else if (P_SuperReady(player, SUPERREADY_DETRANSFORM)) P_DoSuperDetransformation(player); - - player->pflags |= PF_SHIELDDOWN; } } @@ -12054,7 +12086,7 @@ void P_PlayerThink(player_t *player) ticmiss++; P_DoRopeHang(player); - P_DoJumpStuff(player, &player->cmd); + P_DoJumpStuff(player, &player->cmd, false); // P_DoRopeHang would set PF_SPINDOWN, so no spinshieldhack here } else //if (player->powers[pw_carry] == CR_ZOOMTUBE) { @@ -12324,6 +12356,12 @@ void P_PlayerThink(player_t *player) player->pflags &= ~PF_SPINDOWN; } + // Check for Shield button + if (cmd->buttons & BT_SHIELD) + player->pflags |= PF_SHIELDDOWN; + else + player->pflags &= ~PF_SHIELDDOWN; + // IF PLAYER NOT HERE THEN FLASH END IF if (player->quittime && player->powers[pw_flashing] < flashingtics - 1 && !(G_TagGametype() && !(player->pflags & PF_TAGIT)) && !player->gotflag) diff --git a/src/st_stuff.c b/src/st_stuff.c index 67838ddb4..014fbee6e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1170,8 +1170,10 @@ static void ST_drawInput(void) V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_LIVES].f|symb, false) - drawbutt( 4,-3, BT_JUMP, 'J'); - drawbutt(15,-3, BT_SPIN, 'S'); + drawbutt( 4,-3, BT_JUMP, 'J' ); + drawbutt(15,-3, BT_SPIN, 'S' ); + drawbutt(26,-3, BT_SHIELD, '\0'); // Instead of a wide 'J' or 'S', we'll draw a thin "SH" for Shield + V_DrawThinString(x+16+26, y+2+(-3)-offs, hudinfo[HUD_LIVES].f, "SH"); V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_LIVES].f|20); // sundial backing if (stplyr->mo) diff --git a/src/y_inter.c b/src/y_inter.c index bb4fa0690..2add8645b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -579,9 +579,9 @@ void Y_IntermissionDrawer(void) { if (LUA_HudEnabled(hud_intermissiontitletext)) { - const char *ringtext = "\x82" "get 50 rings then"; + const char *ringtext = "\x82" "get 50 rings, then"; const char *tut1text = "\x82" "press " "\x80" "shield"; - const char *tut2text = "\x82" "to " "\x80" "transform"; + const char *tut2text = "\x82" "to transform"; ttheight = 8; V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); ttheight += V_LevelNameHeight(data.spec.passed3) + 2; From 34afebfc060ff41db1c46d4115fbc746c6772720 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 24 Feb 2024 15:41:51 +0100 Subject: [PATCH 13/18] Revert P_SuperReady to a boolean transform type --- src/deh_tables.c | 5 ----- src/lua_baselib.c | 6 ++--- src/p_local.h | 10 +-------- src/p_user.c | 56 ++++++++++++----------------------------------- 4 files changed, 17 insertions(+), 60 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 2ccf80e14..a3b6f2334 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5315,11 +5315,6 @@ struct int_const_s const INT_CONST[] = { //// Masks {"DMG_CANHURTSELF",DMG_CANHURTSELF}, {"DMG_DEATHMASK",DMG_DEATHMASK}, - // For P_SuperReady - {"SUPERREADY_CLASSIC",SUPERREADY_CLASSIC}, - {"SUPERREADY_TRANSFORM",SUPERREADY_TRANSFORM}, - {"SUPERREADY_DETRANSFORM",SUPERREADY_DETRANSFORM}, - {"NUMSUPERREADY",NUMSUPERREADY}, // Intermission types {"int_none",int_none}, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a5162837e..ee5f934a7 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1712,14 +1712,12 @@ static int lib_pResetCamera(lua_State *L) static int lib_pSuperReady(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - superready_t type = luaL_optinteger(L, 2, SUPERREADY_CLASSIC); + boolean transform = (boolean)lua_opttrueboolean(L, 2); //HUDSAFE INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - if (type < 0 || type >= NUMSUPERREADY) - return luaL_error(L, "superready type %d out of range (0 - %d)", type, NUMSUPERREADY-1); - lua_pushboolean(L, P_SuperReady(player, type)); + lua_pushboolean(L, P_SuperReady(player, transform)); return 1; } diff --git a/src/p_local.h b/src/p_local.h index da8956ae1..a4ec0262e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -113,14 +113,6 @@ typedef struct camera_s fixed_t momx, momy, momz; } camera_t; -typedef enum -{ - SUPERREADY_CLASSIC, // Two-button play mode, when Spin and Shield are bound to the same button (pressed on the same tic) - SUPERREADY_TRANSFORM, - SUPERREADY_DETRANSFORM, - NUMSUPERREADY -} superready_t; - extern camera_t camera, camera2; extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height; extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_turnmultiplier, cv_cam_orbit, cv_cam_adjust; @@ -211,7 +203,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user -boolean P_SuperReady(player_t *player, superready_t type); +boolean P_SuperReady(player_t *player, boolean transform); void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip); void P_DoSpinDashDust(player_t *player); #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) diff --git a/src/p_user.c b/src/p_user.c index 30650b5bb..ec8894e6e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4431,47 +4431,18 @@ static void P_DoSuperStuff(player_t *player) // // Returns true if player is ready to transform or detransform // -boolean P_SuperReady(player_t *player, superready_t type) +boolean P_SuperReady(player_t *player, boolean transform) { - switch (type) // Transformation-type-specific checks - { - case SUPERREADY_CLASSIC: - // Pressed Spin and Shield on the same tic? Then you've probably bound them to the same button, - // so let's match the earlier Spin-only button behaviour to still support two-button play - if (!player->powers[pw_super] - && !player->powers[pw_invulnerability] - && !player->powers[pw_tailsfly] - && (player->charflags & SF_SUPER) - && (player->pflags & PF_JUMPED) - && !(player->powers[pw_shield] & SH_NOSTACK) - && !(maptol & TOL_NIGHTS) - && ALL7EMERALDS(emeralds) - && (player->rings >= 50)) - return true; - else - return false; - break; + if (!transform && + (player->powers[pw_super] < TICRATE*3/2 + || !G_CoopGametype())) // No turning back in competitive! + return false; + else if (transform + && (player->powers[pw_super] + || !ALL7EMERALDS(emeralds) + || !(player->rings >= 50))) + return false; - case SUPERREADY_TRANSFORM: - // Turning Super by pressing Shield? - if (player->powers[pw_super] - || !ALL7EMERALDS(emeralds) - || !(player->rings >= 50)) - return false; - break; - - case SUPERREADY_DETRANSFORM: - // Reverting from Super by pressing Shield? - if ((player->powers[pw_super] < TICRATE*3/2) // No spamming the transformation sound! - || !G_CoopGametype()) // No turning back in competitive! - return false; - break; - - default: // "type" is an enum, so having a case for every enum value pleases the compiler - break; - } - - // These checks apply to both SUPERREADY_TRANSFORM and SUPERREADY_DETRANSFORM if (player->mo && !player->powers[pw_tailsfly] && !player->powers[pw_carry] @@ -5335,7 +5306,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhac ; else if (cmd->buttons & BT_SPIN) { - if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player, SUPERREADY_CLASSIC)) + if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player, true) + && !player->powers[pw_invulnerability] && !(player->powers[pw_shield] & SH_NOSTACK)) // These two checks are no longer in P_SuperReady { // If you're using two-button play, can turn Super and aren't already, // and you don't have a shield, then turn Super! @@ -8827,11 +8799,11 @@ void P_MovePlayer(player_t *player) if ((cmd->buttons & BT_SHIELD) && !(player->pflags & PF_SHIELDDOWN) && !spinshieldhack) { // Transform into super if we can! - if (P_SuperReady(player, SUPERREADY_TRANSFORM)) + if (P_SuperReady(player, true)) P_DoSuperTransformation(player, false); // Detransform from super if we can! - else if (P_SuperReady(player, SUPERREADY_DETRANSFORM)) + else if (P_SuperReady(player, false)) P_DoSuperDetransformation(player); } } From f16836bd81d5d5e09cb4653dfef1ad6aa46ac1e0 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sat, 24 Feb 2024 14:43:21 -0300 Subject: [PATCH 14/18] Changes: - Renamed renderwalls, renderfloors and renderthings - Removed CV_NOTINNET|CV_CHEAT from renderwalls, renderfloors and renderthings - Moved some cvars to proper places --- src/d_main.c | 12 ++++++++++++ src/hardware/hw_main.c | 23 +++++++++-------------- src/netcode/d_netcmd.c | 16 +++++++--------- src/netcode/d_netcmd.h | 6 ++++-- src/p_local.h | 1 - src/r_main.c | 38 ++++++++++++++++++++++---------------- src/r_main.h | 10 ++++++++-- src/r_plane.c | 2 +- src/r_segs.c | 2 +- src/r_things.c | 12 ++++++------ src/screen.c | 5 ----- src/screen.h | 4 +--- 12 files changed, 71 insertions(+), 60 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 3886ad1ad..c139650d1 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -476,6 +476,18 @@ static void D_Display(void) if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap))) { // draw the view directly + if (cv_debug) + { + r_renderwalls = cv_renderwalls.value; + r_renderfloors = cv_renderfloors.value; + r_renderthings = cv_renderthings.value; + } + else + { + r_renderwalls = true; + r_renderfloors = true; + r_renderthings = true; + } if (!automapactive && !dedicated && cv_renderview.value) { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0ec4536ce..f5270f4e9 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -339,6 +339,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; + if (!r_renderfloors) + return; + // no convex poly were generated for this subsector if (!xsub->planepoly) return; @@ -483,9 +486,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool PolyFlags |= PF_ColorMapped; } - if (!cv_renderfloors.value) - return; - HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false); if (subsector) @@ -668,7 +668,7 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL { INT32 shader = SHADER_NONE; - if (!cv_renderwalls.value) + if (!r_renderwalls) return; HWR_Lighting(pSurf, lightlevel, wallcolormap); @@ -709,7 +709,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y); extracolormap_t *colormap = NULL; - if (!cv_renderwalls.value) + if (!r_renderwalls) return; realtop = top = wallVerts[3].y; @@ -2108,13 +2108,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - if (nrPlaneVerts < 3) // Not even a triangle? + if (!r_renderfloors || nrPlaneVerts < 3) // Not even a triangle? return; - else if (nrPlaneVerts > (size_t)UINT16_MAX) // FIXME: exceeds plVerts size - { - CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX); - return; - } // Allocate plane-vertex buffer if we need to if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) @@ -4286,7 +4281,7 @@ static void HWR_ProjectSprite(mobj_t *thing) // uncapped/interpolation interpmobjstate_t interp = {0}; - if (!cv_renderthings.value) + if (!r_renderthings) return; if (!thing) @@ -5831,7 +5826,7 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 te { static size_t allocedwalls = 0; - if (!cv_renderwalls.value) + if (!r_renderwalls) return; // Force realloc if buffer has been freed @@ -5862,7 +5857,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, INT32 shader = SHADER_NONE; - if (!cv_renderwalls.value) + if (!r_renderwalls) return; // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 6bdcaa650..c5b402165 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -662,6 +662,13 @@ void D_RegisterClientCommands(void) for (i = 0; i < MAXPLAYERS; i++) sprintf(player_names[i], "Player %d", 1 + i); + CV_RegisterVar(&cv_gravity); + CV_RegisterVar(&cv_tailspickup); + CV_RegisterVar(&cv_allowmlook); + CV_RegisterVar(&cv_flipcam); + CV_RegisterVar(&cv_flipcam2); + CV_RegisterVar(&cv_movebob); + if (dedicated) return; @@ -889,13 +896,6 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); - CV_RegisterVar(&cv_renderview); - CV_RegisterVar(&cv_renderhitboxinterpolation); - CV_RegisterVar(&cv_renderhitboxgldepth); - CV_RegisterVar(&cv_renderhitbox); - CV_RegisterVar(&cv_renderwalls); - CV_RegisterVar(&cv_renderfloors); - CV_RegisterVar(&cv_renderthings); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); @@ -916,8 +916,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_opflags); CV_RegisterVar(&cv_ophoopflags); CV_RegisterVar(&cv_mapthingnum); -// CV_RegisterVar(&cv_grid); -// CV_RegisterVar(&cv_snapto); CV_RegisterVar(&cv_freedemocamera); diff --git a/src/netcode/d_netcmd.h b/src/netcode/d_netcmd.h index e30fa4a02..03c50a2fa 100644 --- a/src/netcode/d_netcmd.h +++ b/src/netcode/d_netcmd.h @@ -94,7 +94,10 @@ extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_p extern consvar_t cv_overtime; extern consvar_t cv_startinglives; -// for F_finale.c +extern consvar_t cv_gravity, cv_movebob; +extern consvar_t cv_tailspickup; + +// for f_finale.c extern consvar_t cv_rollingdemos; extern consvar_t cv_ringslinger, cv_soundtest; @@ -105,7 +108,6 @@ extern consvar_t cv_maxping; extern consvar_t cv_pingtimeout; extern consvar_t cv_showping; - extern consvar_t cv_skipmapcheck; extern consvar_t cv_sleep; diff --git a/src/p_local.h b/src/p_local.h index 9644e7a24..b7b677526 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -283,7 +283,6 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b extern mapthing_t *itemrespawnque[ITEMQUESIZE]; extern tic_t itemrespawntime[ITEMQUESIZE]; extern size_t iquehead, iquetail; -extern consvar_t cv_gravity, cv_movebob; mobjtype_t P_GetMobjtype(UINT16 mthingtype); diff --git a/src/r_main.c b/src/r_main.c index 233e55b82..462439294 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -66,6 +66,10 @@ sector_t *viewsector; player_t *viewplayer; mobj_t *r_viewmobj; +boolean r_renderwalls; +boolean r_renderfloors; +boolean r_renderthings; + fixed_t rendertimefrac; fixed_t renderdeltatics; boolean renderisnewtic; @@ -149,8 +153,6 @@ consvar_t cv_flipcam2 = CVAR_INIT ("flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_ffloorclip = CVAR_INIT ("r_ffloorclip", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_spriteclip = CVAR_INIT ("r_spriteclip", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize); consvar_t cv_translucenthud = CVAR_INIT ("translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL); @@ -161,12 +163,17 @@ consvar_t cv_drawdist_nights = CVAR_INIT ("drawdist_nights", "2048", CV_SAVE, dr consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL); consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_SAVE|CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange); consvar_t cv_fovchange = CVAR_INIT ("fovchange", "Off", CV_SAVE, CV_OnOff, NULL); - -// Okay, whoever said homremoval causes a performance hit should be shot. -consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL); - consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL); +consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL); +consvar_t cv_renderwalls = CVAR_INIT ("r_renderwalls", "On", 0, CV_OnOff, NULL); +consvar_t cv_renderfloors = CVAR_INIT ("r_renderfloors", "On", 0, CV_OnOff, NULL); +consvar_t cv_renderthings = CVAR_INIT ("r_renderthings", "On", 0, CV_OnOff, NULL); +consvar_t cv_ffloorclip = CVAR_INIT ("r_ffloorclip", "On", 0, CV_OnOff, NULL); +consvar_t cv_spriteclip = CVAR_INIT ("r_spriteclip", "On", 0, CV_OnOff, NULL); + +consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL); + consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL); void SplitScreen_OnChange(void) @@ -1613,17 +1620,11 @@ void R_RenderPlayerView(player_t *player) void R_RegisterEngineStuff(void) { - CV_RegisterVar(&cv_gravity); - CV_RegisterVar(&cv_tailspickup); - CV_RegisterVar(&cv_allowmlook); - CV_RegisterVar(&cv_homremoval); - CV_RegisterVar(&cv_flipcam); - CV_RegisterVar(&cv_flipcam2); - - // Enough for dedicated server + // Do nothing for dedicated server if (dedicated) return; + CV_RegisterVar(&cv_homremoval); CV_RegisterVar(&cv_translucency); CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist_nights); @@ -1636,6 +1637,13 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_shadow); CV_RegisterVar(&cv_skybox); + CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderhitboxinterpolation); + CV_RegisterVar(&cv_renderhitboxgldepth); + CV_RegisterVar(&cv_renderhitbox); + CV_RegisterVar(&cv_renderwalls); + CV_RegisterVar(&cv_renderfloors); + CV_RegisterVar(&cv_renderthings); CV_RegisterVar(&cv_ffloorclip); CV_RegisterVar(&cv_spriteclip); @@ -1674,8 +1682,6 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_maxportals); - CV_RegisterVar(&cv_movebob); - // Frame interpolation/uncapped CV_RegisterVar(&cv_fpscap); } diff --git a/src/r_main.h b/src/r_main.h index da2189328..aedfeb6ad 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -119,12 +119,18 @@ extern consvar_t cv_chasecam, cv_chasecam2; extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_shadow; -extern consvar_t cv_ffloorclip, cv_spriteclip; extern consvar_t cv_translucency; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_fov, cv_fovchange; extern consvar_t cv_skybox; -extern consvar_t cv_tailspickup; +extern consvar_t cv_renderview; +extern consvar_t cv_renderhitbox, cv_renderhitboxinterpolation, cv_renderhitboxgldepth; +extern consvar_t cv_renderwalls, cv_renderfloors, cv_renderthings; +extern consvar_t cv_ffloorclip, cv_spriteclip; + +extern boolean r_renderwalls; +extern boolean r_renderfloors; +extern boolean r_renderthings; // Called by startup code. void R_Init(void); diff --git a/src/r_plane.c b/src/r_plane.c index cad2dd49f..33e3aac13 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -603,7 +603,7 @@ void R_DrawPlanes(void) visplane_t *pl; INT32 i; - if (!cv_renderfloors.value) + if (!r_renderfloors) return; R_UpdatePlaneRipple(); diff --git a/src/r_segs.c b/src/r_segs.c index 6656127fe..a10ddfd37 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1066,7 +1066,7 @@ static void R_RenderSegLoop (void) drawbottom = R_DrawFlippedWall; } - if (!cv_renderwalls.value) + if (!r_renderwalls) { drawtop = R_DrawNoWall; drawmiddle = R_DrawNoWall; diff --git a/src/r_things.c b/src/r_things.c index 80b6816db..642269909 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1537,7 +1537,7 @@ static void R_ProjectSprite(mobj_t *thing) // uncapped/interpolation interpmobjstate_t interp = {0}; - if (!cv_renderthings.value) + if (!r_renderthings) return; // do interpolation @@ -2694,7 +2694,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps // Add the 3D floors, thicksides, and masked textures... for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];) { - if (ds->numthicksides && cv_renderwalls.value) + if (ds->numthicksides && r_renderwalls) { for (i = 0; i < ds->numthicksides; i++) { @@ -2713,19 +2713,19 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps else { // Put it in! entry = R_CreateDrawNode(head); - if (cv_renderwalls.value) + if (r_renderwalls) entry->seg = ds; - if (cv_renderfloors.value) + if (r_renderfloors) entry->plane = plane; } ds->curline->polyseg->visplane = NULL; } - if (ds->maskedtexturecol && cv_renderwalls.value) + if (ds->maskedtexturecol && r_renderwalls) { entry = R_CreateDrawNode(head); entry->seg = ds; } - if (ds->numffloorplanes && cv_renderfloors.value) + if (ds->numffloorplanes && r_renderfloors) { for (i = 0; i < ds->numffloorplanes; i++) { diff --git a/src/screen.c b/src/screen.c index c1970d0e8..13de69fcb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -70,11 +70,6 @@ consvar_t cv_scr_width_w = CVAR_INIT ("scr_width_w", "640", CV_SAVE, CV_Unsigned consvar_t cv_scr_height_w = CVAR_INIT ("scr_height_w", "400", CV_SAVE, CV_Unsigned, NULL); consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL); -consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL); -consvar_t cv_renderwalls = CVAR_INIT ("renderwalls", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_renderfloors = CVAR_INIT ("renderfloors", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_renderthings = CVAR_INIT ("renderthings", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL); - CV_PossibleValue_t cv_renderer_t[] = { {1, "Software"}, #ifdef HWRENDER diff --git a/src/screen.h b/src/screen.h index 5df5d2889..8b952e553 100644 --- a/src/screen.h +++ b/src/screen.h @@ -157,9 +157,7 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern consvar_t cv_scr_width, cv_scr_height, cv_scr_width_w, cv_scr_height_w, cv_scr_depth, cv_fullscreen; -extern consvar_t cv_renderwalls, cv_renderfloors, cv_renderthings; -extern consvar_t cv_renderview, cv_renderer; -extern consvar_t cv_renderhitbox, cv_renderhitboxinterpolation, cv_renderhitboxgldepth; +extern consvar_t cv_renderer; // wait for page flipping to end or not extern consvar_t cv_vidwait; extern consvar_t cv_timescale; From a73f9476f33cfa78ea2d7a2a4e22847477bd6ac1 Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Sat, 24 Feb 2024 23:57:09 -0500 Subject: [PATCH 15/18] fixed call to P_SetScale() within A_MinusDigging() that I missed --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 0fa392b28..428c023ff 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5816,7 +5816,7 @@ void A_MinusDigging(mobj_t *actor) P_SetMobjState(par, actor->info->raisestate); if (P_MobjWasRemoved(par)) return; - P_SetScale(par, actor->scale*2); + P_SetScale(par, actor->scale*2, false); par->old_scale = par->scale; if (actor->eflags & MFE_VERTICALFLIP) par->eflags |= MFE_VERTICALFLIP; From 853afa30df355171810eb0b5c37a7e61e2f2f6df Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sat, 2 Mar 2024 18:51:56 +0100 Subject: [PATCH 16/18] Fix missing HUD item for Lua --- src/doomdef.h | 2 ++ src/lua_hudlib.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/doomdef.h b/src/doomdef.h index 60e7dc203..d1ad93fcc 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -82,6 +82,7 @@ #include "version.h" #include "doomtype.h" +#include #include #include #include @@ -648,6 +649,7 @@ UINT32 quickncasehash (const char *p, size_t n) #else #define I_Assert(e) ((void)0) #endif +#define I_StaticAssert(e) static_assert(e) // The character that separates pathnames. Forward slash on // most systems, but reverse solidus (\) on Windows. diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index d66521263..08e0367f9 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -47,6 +47,7 @@ static const char *const hud_disable_options[] = { "time", "rings", "lives", + "input", "weaponrings", "powerstones", @@ -70,6 +71,10 @@ static const char *const hud_disable_options[] = { "intermissionemeralds", NULL}; +// you know, let's actually make sure that the table is synced. +// because fuck knows how many times this has happened at this point. :v +I_StaticAssert(sizeof(hud_disable_options) / sizeof(*hud_disable_options) == hud_MAX+1); + enum hudinfo { hudinfo_x = 0, hudinfo_y, From 8ea215bf2fff5b65d1abf8149f0b7b0255eabe69 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sun, 3 Mar 2024 11:36:29 +0100 Subject: [PATCH 17/18] Fix compiler error in clang --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index d1ad93fcc..1b0e76314 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -649,7 +649,7 @@ UINT32 quickncasehash (const char *p, size_t n) #else #define I_Assert(e) ((void)0) #endif -#define I_StaticAssert(e) static_assert(e) +#define I_StaticAssert(e) static_assert(e, "Static assertion failed: " #e) // The character that separates pathnames. Forward slash on // most systems, but reverse solidus (\) on Windows. From f372f07bf46e0e4e0fdd69075254800c8b68f5af Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Sun, 3 Mar 2024 12:15:12 -0500 Subject: [PATCH 18/18] libpng for everyone zlib and libpng are now always needed --- src/Makefile | 4 ---- src/Makefile.d/features.mk | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/Makefile b/src/Makefile index 6dba19c24..40037834d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -47,8 +47,6 @@ # HAVE_MINIUPNPC=1 - Enable automated port forwarding. # Already enabled by default for 32-bit # Windows. -# NOPNG=1 - Disable PNG graphics support. (TODO: double -# check netplay compatible.) # NOCURL=1 - Disable libcurl--HTTP capability. # NOGME=1 - Disable game music emu, retro VGM support. # NOOPENMPT=1 - Disable module (tracker) music support. @@ -69,8 +67,6 @@ # NOEXECINFO=1 - Disable stack trace dump support # DEBUGMODE=1 - Enable various debugging capabilities. # Also disables optimizations. -# NOZLIB=1 - Disable some compression capability. Implies -# NOPNG=1. # # Development flags: # diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index d132ecc9e..59806862d 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -22,8 +22,6 @@ ifndef NOMD5 sources+=md5.c endif -ifndef NOZLIB -ifndef NOPNG ifdef PNG_PKGCONFIG $(eval $(call Use_pkg_config,PNG_PKGCONFIG)) else @@ -36,8 +34,6 @@ opts+=-D_LARGEFILE64_SOURCE endif opts+=-DHAVE_PNG sources+=apng.c -endif -endif ifndef NOCURL CURLCONFIG?=curl-config