Merge branch 'master' into Clip3DLights

This commit is contained in:
Christoph Oelckers 2016-01-31 10:10:32 +01:00
commit 4d7e7deea8
32 changed files with 435 additions and 368 deletions

View File

@ -369,14 +369,6 @@ bool FCajunMaster::DoAddBot (BYTE *info, botskill_t skill)
D_ReadUserInfoStrings (bnum, &info, false); D_ReadUserInfoStrings (bnum, &info, false);
if (!deathmatch && playerstarts[bnum].type == 0)
{
Printf ("%s tried to join, but there was no player %d start\n",
players[bnum].userinfo.GetName(), bnum+1);
ClearPlayer (bnum, false); // Make the bot inactive again
return false;
}
multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost). multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost).
players[bnum].Bot = new DBot; players[bnum].Bot = new DBot;
players[bnum].Bot->player = &players[bnum]; players[bnum].Bot->player = &players[bnum];

View File

@ -60,7 +60,7 @@
static FRandom pr_pickteam ("PickRandomTeam"); static FRandom pr_pickteam ("PickRandomTeam");
CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Float, autoaim, 35.f, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Int, colorset, 0, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Int, colorset, 0, CVAR_USERINFO | CVAR_ARCHIVE);
@ -518,9 +518,9 @@ void D_UserInfoChanged (FBaseCVar *cvar)
autoaim = 0.0f; autoaim = 0.0f;
return; return;
} }
else if (autoaim > 5000.0f) else if (autoaim > 35.0f)
{ {
autoaim = 5000.f; autoaim = 35.f;
return; return;
} }
} }

View File

@ -492,6 +492,7 @@ public:
crouchdir = 0; crouchdir = 0;
crouching = 0; crouching = 0;
crouchviewdelta = 0; crouchviewdelta = 0;
viewheight = mo->ViewHeight;
} }
bool CanCrouch() const bool CanCrouch() const

View File

@ -1082,7 +1082,7 @@ void FParser::SF_Teleport(void)
} }
if(mo) if(mo)
EV_Teleport(0, tag, NULL, 0, mo, true, true, false); EV_Teleport(0, tag, NULL, 0, mo, TELF_DESTFOG | TELF_SOURCEFOG);
} }
} }
@ -1111,7 +1111,7 @@ void FParser::SF_SilentTeleport(void)
} }
if(mo) if(mo)
EV_Teleport(0, tag, NULL, 0, mo, false, false, true); EV_Teleport(0, tag, NULL, 0, mo, TELF_KEEPORIENTATION);
} }
} }

View File

@ -1422,6 +1422,8 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing)
fixed_t z, oldz; fixed_t z, oldz;
int i; int i;
if (mthing->type == 0) return false;
x = mthing->x; x = mthing->x;
y = mthing->y; y = mthing->y;
z = mthing->z; z = mthing->z;
@ -1573,6 +1575,11 @@ void G_DeathMatchSpawnPlayer (int playernum)
// //
FPlayerStart *G_PickPlayerStart(int playernum, int flags) FPlayerStart *G_PickPlayerStart(int playernum, int flags)
{ {
if (AllPlayerStarts.Size() == 0) // No starts to pick
{
return NULL;
}
if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) || if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) ||
playerstarts[playernum].type == 0) playerstarts[playernum].type == 0)
{ {
@ -1624,6 +1631,18 @@ static void G_QueueBody (AActor *body)
translationtables[TRANSLATION_PlayerCorpses][modslot]->UpdateNative(); translationtables[TRANSLATION_PlayerCorpses][modslot]->UpdateNative();
} }
const int skinidx = body->player->userinfo.GetSkin();
if (0 != skinidx && !(body->flags4 & MF4_NOSKIN))
{
// Apply skin's scale to actor's scale, it will be lost otherwise
const AActor *const defaultActor = body->GetDefault();
const FPlayerSkin &skin = skins[skinidx];
body->scaleX = Scale(body->scaleX, skin.ScaleX, defaultActor->scaleX);
body->scaleY = Scale(body->scaleY, skin.ScaleY, defaultActor->scaleY);
}
bodyqueslot++; bodyqueslot++;
} }
@ -2629,12 +2648,12 @@ bool G_ProcessIFFDemo (FString &mapname)
if (uncompSize > 0) if (uncompSize > 0)
{ {
BYTE *uncompressed = new BYTE[uncompSize]; BYTE *uncompressed = (BYTE*)M_Malloc(uncompSize);
int r = uncompress (uncompressed, &uncompSize, demo_p, uLong(zdembodyend - demo_p)); int r = uncompress (uncompressed, &uncompSize, demo_p, uLong(zdembodyend - demo_p));
if (r != Z_OK) if (r != Z_OK)
{ {
Printf ("Could not decompress demo! %s\n", M_ZLibError(r).GetChars()); Printf ("Could not decompress demo! %s\n", M_ZLibError(r).GetChars());
delete[] uncompressed; M_Free(uncompressed);
return true; return true;
} }
M_Free (demobuffer); M_Free (demobuffer);

View File

@ -97,7 +97,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
spot = iterator.Next (); spot = iterator.Next ();
if (spot != NULL) if (spot != NULL)
{ {
P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, true, true, false); P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG);
} }
P_StartScript (self, NULL, 249, NULL, NULL, 0, 0); P_StartScript (self, NULL, 249, NULL, NULL, 0, 0);
@ -136,7 +136,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
self->tracer = spot; self->tracer = spot;
if (spot) if (spot)
{ {
P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, true, true, false); P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG);
} }
} }
} }

View File

@ -162,7 +162,7 @@ void P_TeleportToPlayerStarts (AActor *victim)
destX = start->x; destX = start->x;
destY = start->y; destY = start->y;
destAngle = ANG45 * (start->angle/45); destAngle = ANG45 * (start->angle/45);
P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false); P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
} }
//=========================================================================== //===========================================================================
@ -184,7 +184,7 @@ void P_TeleportToDeathmatchStarts (AActor *victim)
destX = deathmatchstarts[i].x; destX = deathmatchstarts[i].x;
destY = deathmatchstarts[i].y; destY = deathmatchstarts[i].y;
destAngle = ANG45 * (deathmatchstarts[i].angle/45); destAngle = ANG45 * (deathmatchstarts[i].angle/45);
P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false); P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
} }
else else
{ {

View File

@ -1195,74 +1195,83 @@ void G_FinishTravel ()
TThinkerIterator<APlayerPawn> it (STAT_TRAVELLING); TThinkerIterator<APlayerPawn> it (STAT_TRAVELLING);
APlayerPawn *pawn, *pawndup, *oldpawn, *next; APlayerPawn *pawn, *pawndup, *oldpawn, *next;
AInventory *inv; AInventory *inv;
FPlayerStart *start;
int pnum;
next = it.Next (); next = it.Next ();
while ( (pawn = next) != NULL) while ( (pawn = next) != NULL)
{ {
next = it.Next (); next = it.Next ();
pnum = int(pawn->player - players);
pawn->ChangeStatNum (STAT_PLAYER); pawn->ChangeStatNum (STAT_PLAYER);
pawndup = pawn->player->mo; pawndup = pawn->player->mo;
start = NULL;
assert (pawn != pawndup); assert (pawn != pawndup);
if (pawndup == NULL) if (pawndup == NULL)
{ // Oh no! there was no start for this player! { // Oh no! there was no start for this player!
pawn->flags |= MF_NOSECTOR|MF_NOBLOCKMAP; start = G_PickPlayerStart(pnum, PPS_FORCERANDOM);
pawn->Destroy (); if (start != NULL) pawndup = P_SpawnPlayer(start, pnum, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
if (pawndup == NULL)
{
pawn->flags |= MF_NOSECTOR | MF_NOBLOCKMAP;
pawn->Destroy();
continue;
}
} }
else
if (start == NULL) start = G_PickPlayerStart(pnum, 0);
oldpawn = pawndup;
// The player being spawned here is a short lived dummy and
// must not start any ENTER script or big problems will happen.
pawndup = P_SpawnPlayer(start, pnum, SPF_TEMPPLAYER);
if (!(changeflags & CHANGELEVEL_KEEPFACING))
{ {
oldpawn = pawndup; pawn->angle = pawndup->angle;
pawn->pitch = pawndup->pitch;
}
pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z());
pawn->velx = pawndup->velx;
pawn->vely = pawndup->vely;
pawn->velz = pawndup->velz;
pawn->Sector = pawndup->Sector;
pawn->floorz = pawndup->floorz;
pawn->ceilingz = pawndup->ceilingz;
pawn->dropoffz = pawndup->dropoffz;
pawn->floorsector = pawndup->floorsector;
pawn->floorpic = pawndup->floorpic;
pawn->floorterrain = pawndup->floorterrain;
pawn->ceilingsector = pawndup->ceilingsector;
pawn->ceilingpic = pawndup->ceilingpic;
pawn->floorclip = pawndup->floorclip;
pawn->waterlevel = pawndup->waterlevel;
pawn->target = NULL;
pawn->lastenemy = NULL;
pawn->player->mo = pawn;
pawn->player->camera = pawn;
pawn->player->viewheight = pawn->ViewHeight;
pawn->flags2 &= ~MF2_BLASTED;
DObject::StaticPointerSubstitution (oldpawn, pawn);
oldpawn->Destroy();
pawndup->Destroy ();
pawn->LinkToWorld ();
pawn->AddToHash ();
pawn->SetState(pawn->SpawnState);
pawn->player->SendPitchLimits();
// The player being spawned here is a short lived dummy and for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory)
// must not start any ENTER script or big problems will happen. {
pawndup = P_SpawnPlayer (&playerstarts[pawn->player - players], int(pawn->player - players), SPF_TEMPPLAYER); inv->ChangeStatNum (STAT_INVENTORY);
if (!(changeflags & CHANGELEVEL_KEEPFACING)) inv->LinkToWorld ();
{ inv->Travelled ();
pawn->angle = pawndup->angle; }
pawn->pitch = pawndup->pitch; if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED)
} {
pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z()); pawn->Speed = pawn->GetDefault()->Speed;
pawn->velx = pawndup->velx; }
pawn->vely = pawndup->vely; if (level.FromSnapshot)
pawn->velz = pawndup->velz; {
pawn->Sector = pawndup->Sector; FBehavior::StaticStartTypedScripts (SCRIPT_Return, pawn, true);
pawn->floorz = pawndup->floorz;
pawn->ceilingz = pawndup->ceilingz;
pawn->dropoffz = pawndup->dropoffz;
pawn->floorsector = pawndup->floorsector;
pawn->floorpic = pawndup->floorpic;
pawn->floorterrain = pawndup->floorterrain;
pawn->ceilingsector = pawndup->ceilingsector;
pawn->ceilingpic = pawndup->ceilingpic;
pawn->floorclip = pawndup->floorclip;
pawn->waterlevel = pawndup->waterlevel;
pawn->target = NULL;
pawn->lastenemy = NULL;
pawn->player->mo = pawn;
pawn->player->camera = pawn;
pawn->player->viewheight = pawn->ViewHeight;
pawn->flags2 &= ~MF2_BLASTED;
DObject::StaticPointerSubstitution (oldpawn, pawn);
oldpawn->Destroy();
pawndup->Destroy ();
pawn->LinkToWorld ();
pawn->AddToHash ();
pawn->SetState(pawn->SpawnState);
pawn->player->SendPitchLimits();
for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory)
{
inv->ChangeStatNum (STAT_INVENTORY);
inv->LinkToWorld ();
inv->Travelled ();
}
if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED)
{
pawn->Speed = pawn->GetDefault()->Speed;
}
if (level.FromSnapshot)
{
FBehavior::StaticStartTypedScripts (SCRIPT_Return, pawn, true);
}
} }
} }

View File

@ -43,7 +43,7 @@ bool AArtiTeleport::Use (bool pickup)
destY = start->y; destY = start->y;
destAngle = ANG45 * (start->angle/45); destAngle = ANG45 * (start->angle/45);
} }
P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false); P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
bool canlaugh = true; bool canlaugh = true;
if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE)) if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE))
{ // Teleporting away will undo any morph effects (pig) { // Teleporting away will undo any morph effects (pig)

View File

@ -1500,7 +1500,9 @@ void APowerTimeFreezer::InitEffect()
} }
else else
{ {
EffectTics++; // Compensate for skipped tic, but beware of overflow.
if(EffectTics < INT_MAX)
EffectTics++;
} }
} }

View File

@ -70,7 +70,7 @@ void AFastProjectile::Tick ()
{ {
if (--ripcount <= 0) if (--ripcount <= 0)
{ {
tm.LastRipped = NULL; // [RH] Do rip damage each step, like Hexen tm.LastRipped.Clear(); // [RH] Do rip damage each step, like Hexen
} }
if (!P_TryMove (this, X() + xfrac,Y() + yfrac, true, NULL, tm)) if (!P_TryMove (this, X() + xfrac,Y() + yfrac, true, NULL, tm))

View File

@ -591,6 +591,9 @@ void DIntermissionScreenCast::Drawer ()
// draw the current frame in the middle of the screen // draw the current frame in the middle of the screen
if (caststate != NULL) if (caststate != NULL)
{ {
double castscalex = FIXED2DBL(mDefaults->scaleX);
double castscaley = FIXED2DBL(mDefaults->scaleY);
int castsprite = caststate->sprite; int castsprite = caststate->sprite;
if (!(mDefaults->flags4 & MF4_NOSKIN) && if (!(mDefaults->flags4 & MF4_NOSKIN) &&
@ -604,7 +607,15 @@ void DIntermissionScreenCast::Drawer ()
{ {
if (PlayerClasses[i].Type == mClass) if (PlayerClasses[i].Type == mClass)
{ {
castsprite = skins[players[consoleplayer].userinfo.GetSkin()].sprite; FPlayerSkin *skin = &skins[players[consoleplayer].userinfo.GetSkin()];
castsprite = skin->sprite;
if (!(mDefaults->flags4 & MF4_NOSKIN))
{
castscaley = FIXED2DBL(skin->ScaleY);
castscalex = FIXED2DBL(skin->ScaleX);
}
} }
} }
} }
@ -615,6 +626,10 @@ void DIntermissionScreenCast::Drawer ()
screen->DrawTexture (pic, 160, 170, screen->DrawTexture (pic, 160, 170,
DTA_320x200, true, DTA_320x200, true,
DTA_FlipX, sprframe->Flip & 1, DTA_FlipX, sprframe->Flip & 1,
DTA_DestHeightF, pic->GetScaledHeightDouble() * castscaley,
DTA_DestWidthF, pic->GetScaledWidthDouble() * castscalex,
DTA_RenderStyle, mDefaults->RenderStyle,
DTA_Alpha, mDefaults->alpha,
DTA_Translation, casttranslation, DTA_Translation, casttranslation,
TAG_DONE); TAG_DONE);
} }

View File

@ -479,7 +479,8 @@ void FSliderItem::Drawer(bool selected)
screen->DrawText(mFont, selected? OptionSettings.mFontColorSelection : mFontColor, mXpos, mYpos, text, DTA_Clean, true, TAG_DONE); screen->DrawText(mFont, selected? OptionSettings.mFontColorSelection : mFontColor, mXpos, mYpos, text, DTA_Clean, true, TAG_DONE);
int x = SmallFont->StringWidth ("Green") + 8 + mXpos; int x = SmallFont->StringWidth ("Green") + 8 + mXpos;
DrawSlider (x, mYpos); int x2 = SmallFont->StringWidth (mText) + 8 + mXpos;
DrawSlider (MAX(x2, x), mYpos);
} }
@ -630,14 +631,7 @@ void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
li = GetItem(NAME_Autoaim); li = GetItem(NAME_Autoaim);
if (li != NULL) if (li != NULL)
{ {
int sel = li->SetValue(0, (int)autoaim);
autoaim == 0 ? 0 :
autoaim <= 0.25 ? 1 :
autoaim <= 0.5 ? 2 :
autoaim <= 1 ? 3 :
autoaim <= 2 ? 4 :
autoaim <= 3 ? 5:6;
li->SetValue(0, sel);
} }
li = GetItem(NAME_Switch); li = GetItem(NAME_Switch);
@ -966,13 +960,11 @@ void DPlayerMenu::SkinChanged (FListMenuItem *li)
void DPlayerMenu::AutoaimChanged (FListMenuItem *li) void DPlayerMenu::AutoaimChanged (FListMenuItem *li)
{ {
static const float ranges[] = { 0, 0.25, 0.5, 1, 2, 3, 5000 };
int sel; int sel;
if (li->GetValue(0, &sel)) if (li->GetValue(0, &sel))
{ {
autoaim = ranges[sel]; autoaim = (float)sel;
} }
} }

View File

@ -132,7 +132,9 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE )
{ {
if ( self == 0 ) if ( self == 0 )
self = 4000; self = 4000;
else if ( self < 100 ) else if (self > 65535)
self = 65535;
else if (self < 100)
self = 100; self = 100;
if ( gamestate != GS_STARTUP ) if ( gamestate != GS_STARTUP )

View File

@ -1114,7 +1114,8 @@ static void CreateCachedNodes(MapData *map)
for(int i=0;i<numsegs;i++) for(int i=0;i<numsegs;i++)
{ {
WriteLong(ZNodes, DWORD(segs[i].v1 - vertexes)); WriteLong(ZNodes, DWORD(segs[i].v1 - vertexes));
WriteLong(ZNodes, DWORD(glsegextras[i].PartnerSeg)); if (glsegextras != NULL) WriteLong(ZNodes, DWORD(glsegextras[i].PartnerSeg));
else WriteLong(ZNodes, 0);
if (segs[i].linedef) if (segs[i].linedef)
{ {
WriteLong(ZNodes, DWORD(segs[i].linedef - lines)); WriteLong(ZNodes, DWORD(segs[i].linedef - lines));

View File

@ -880,19 +880,38 @@ FUNC(LS_Teleport_NewMap)
FUNC(LS_Teleport) FUNC(LS_Teleport)
// Teleport (tid, sectortag, bNoSourceFog) // Teleport (tid, sectortag, bNoSourceFog)
{ {
return EV_Teleport (arg0, arg1, ln, backSide, it, true, !arg2, false); int flags = TELF_DESTFOG;
if (!arg2)
{
flags |= TELF_SOURCEFOG;
}
return EV_Teleport (arg0, arg1, ln, backSide, it, flags);
} }
FUNC( LS_Teleport_NoStop ) FUNC( LS_Teleport_NoStop )
// Teleport_NoStop (tid, sectortag, bNoSourceFog) // Teleport_NoStop (tid, sectortag, bNoSourceFog)
{ {
return EV_Teleport( arg0, arg1, ln, backSide, it, true, !arg2, false, false ); int flags = TELF_DESTFOG | TELF_KEEPVELOCITY;
if (!arg2)
{
flags |= TELF_SOURCEFOG;
}
return EV_Teleport( arg0, arg1, ln, backSide, it, flags);
} }
FUNC(LS_Teleport_NoFog) FUNC(LS_Teleport_NoFog)
// Teleport_NoFog (tid, useang, sectortag, keepheight) // Teleport_NoFog (tid, useang, sectortag, keepheight)
{ {
return EV_Teleport (arg0, arg2, ln, backSide, it, false, false, !arg1, true, !!arg3); int flags = 0;
if (arg1)
{
flags |= TELF_KEEPORIENTATION;
}
if (arg3)
{
flags |= TELF_KEEPHEIGHT;
}
return EV_Teleport (arg0, arg2, ln, backSide, it, flags);
} }
FUNC(LS_Teleport_ZombieChanger) FUNC(LS_Teleport_ZombieChanger)
@ -901,7 +920,7 @@ FUNC(LS_Teleport_ZombieChanger)
// This is practically useless outside of Strife, but oh well. // This is practically useless outside of Strife, but oh well.
if (it != NULL) if (it != NULL)
{ {
EV_Teleport (arg0, arg1, ln, backSide, it, false, false, false); EV_Teleport (arg0, arg1, ln, backSide, it, 0);
if (it->health >= 0) it->SetState (it->FindState(NAME_Pain)); if (it->health >= 0) it->SetState (it->FindState(NAME_Pain));
return true; return true;
} }

View File

@ -445,13 +445,12 @@ struct FCheckPosition
// [RH] These are used by PIT_CheckThing and P_XYMovement to apply // [RH] These are used by PIT_CheckThing and P_XYMovement to apply
// ripping damage once per tic instead of once per move. // ripping damage once per tic instead of once per move.
bool DoRipping; bool DoRipping;
AActor *LastRipped; TMap<AActor*, bool> LastRipped;
int PushTime; int PushTime;
FCheckPosition(bool rip=false) FCheckPosition(bool rip=false)
{ {
DoRipping = rip; DoRipping = rip;
LastRipped = NULL;
PushTime = 0; PushTime = 0;
FromPMove = false; FromPMove = false;
} }

View File

@ -1286,9 +1286,10 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
{ {
if (!(tm.thing->flags6 & MF6_NOBOSSRIP) || !(thing->flags2 & MF2_BOSS)) if (!(tm.thing->flags6 & MF6_NOBOSSRIP) || !(thing->flags2 & MF2_BOSS))
{ {
if (tm.LastRipped != thing) bool *check = tm.LastRipped.CheckKey(thing);
if (check == NULL || !*check)
{ {
tm.LastRipped = thing; tm.LastRipped[thing] = true;
if (!(thing->flags & MF_NOBLOOD) && if (!(thing->flags & MF_NOBLOOD) &&
!(thing->flags2 & MF2_REFLECTIVE) && !(thing->flags2 & MF2_REFLECTIVE) &&
!(tm.thing->flags3 & MF3_BLOODLESSIMPACT) && !(tm.thing->flags3 & MF3_BLOODLESSIMPACT) &&

View File

@ -4431,6 +4431,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
( gameaction != ga_worlddone ) && ( gameaction != ga_worlddone ) &&
( p->mo != NULL ) && ( p->mo != NULL ) &&
( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) && ( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) &&
( NULL != p->attacker ) && // don't respawn on damaging floors
( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) // this really should be a bit smarter... ( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) // this really should be a bit smarter...
{ {
spawn_x = p->mo->X(); spawn_x = p->mo->X();

View File

@ -902,13 +902,22 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag);
// //
// P_TELEPT // P_TELEPT
// //
enum
{
TELF_DESTFOG = 1,
TELF_SOURCEFOG = 2,
TELF_KEEPORIENTATION = 4,
TELF_KEEPVELOCITY = 8,
TELF_KEEPHEIGHT = 16,
};
void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele = true, bool setTarget = false); //Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false). void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele = true, bool setTarget = false); //Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false).
inline void P_SpawnTeleportFog(AActor *mobj, const fixedvec3 &pos, bool beforeTele = true, bool setTarget = false) inline void P_SpawnTeleportFog(AActor *mobj, const fixedvec3 &pos, bool beforeTele = true, bool setTarget = false)
{ {
P_SpawnTeleportFog(mobj, pos.x, pos.y, pos.z, beforeTele, setTarget); P_SpawnTeleportFog(mobj, pos.x, pos.y, pos.z, beforeTele, setTarget);
} }
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false); bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int flags); // bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false); bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags);
bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse); bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse);
bool EV_TeleportOther (int other_tid, int dest_tid, bool fog); bool EV_TeleportOther (int other_tid, int dest_tid, bool fog);
bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog); bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog);

View File

@ -96,8 +96,7 @@ void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool befo
// TELEPORTATION // TELEPORTATION
// //
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int flags)
bool useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity, bool keepHeight)
{ {
bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING)); bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));
@ -123,7 +122,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
{ // We don't measure z velocity, because it doesn't change. { // We don't measure z velocity, because it doesn't change.
missilespeed = xs_CRoundToInt(TVector2<double>(thing->velx, thing->vely).Length()); missilespeed = xs_CRoundToInt(TVector2<double>(thing->velx, thing->vely).Length());
} }
if (keepHeight) if (flags & TELF_KEEPHEIGHT)
{ {
z = floorheight + aboveFloor; z = floorheight + aboveFloor;
} }
@ -142,7 +141,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
else else
{ {
z = floorheight; z = floorheight;
if (!keepOrientation) if (!(flags & TELF_KEEPORIENTATION))
{ {
resetpitch = false; resetpitch = false;
} }
@ -173,7 +172,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
player->mo->pitch = 0; player->mo->pitch = 0;
} }
} }
if (!keepOrientation) if (!(flags & TELF_KEEPORIENTATION))
{ {
thing->angle = angle; thing->angle = angle;
} }
@ -182,11 +181,11 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
angle = thing->angle; angle = thing->angle;
} }
// Spawn teleport fog at source and destination // Spawn teleport fog at source and destination
if (sourceFog && !predicting) if ((flags & TELF_SOURCEFOG) && !predicting)
{ {
P_SpawnTeleportFog(thing, old, true, true); //Passes the actor through which then pulls the TeleFog metadata types based on properties. P_SpawnTeleportFog(thing, old, true, true); //Passes the actor through which then pulls the TeleFog metadata types based on properties.
} }
if (useFog) if (flags & TELF_DESTFOG)
{ {
if (!predicting) if (!predicting)
{ {
@ -199,12 +198,12 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
{ {
// [RH] Zoom player's field of vision // [RH] Zoom player's field of vision
// [BC] && bHaltVelocity. // [BC] && bHaltVelocity.
if (telezoom && thing->player->mo == thing && bHaltVelocity) if (telezoom && thing->player->mo == thing && !(flags & TELF_KEEPVELOCITY))
thing->player->FOV = MIN (175.f, thing->player->DesiredFOV + 45.f); thing->player->FOV = MIN (175.f, thing->player->DesiredFOV + 45.f);
} }
} }
// [BC] && bHaltVelocity. // [BC] && bHaltVelocity.
if (thing->player && (useFog || !keepOrientation) && bHaltVelocity) if (thing->player && ((flags & TELF_DESTFOG) || !(flags & TELF_KEEPORIENTATION)) && !(flags & TELF_KEEPVELOCITY))
{ {
// Freeze player for about .5 sec // Freeze player for about .5 sec
if (thing->Inventory == NULL || !thing->Inventory->GetNoTeleportFreeze()) if (thing->Inventory == NULL || !thing->Inventory->GetNoTeleportFreeze())
@ -217,8 +216,8 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
thing->vely = FixedMul (missilespeed, finesine[angle]); thing->vely = FixedMul (missilespeed, finesine[angle]);
} }
// [BC] && bHaltVelocity. // [BC] && bHaltVelocity.
else if (!keepOrientation && bHaltVelocity) // no fog doesn't alter the player's momentum else if (!(flags & TELF_KEEPORIENTATION) && !(flags & TELF_KEEPVELOCITY))
{ { // no fog doesn't alter the player's momentum
thing->velx = thing->vely = thing->velz = 0; thing->velx = thing->vely = thing->velz = 0;
// killough 10/98: kill all bobbing velocity too // killough 10/98: kill all bobbing velocity too
if (player) if (player)
@ -322,10 +321,8 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom)
return NULL; return NULL;
} }
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags)
bool sourceFog, bool keepOrientation, bool haltVelocity, bool keepHeight)
{ {
AActor *searcher; AActor *searcher;
fixed_t z; fixed_t z;
angle_t angle = 0; angle_t angle = 0;
@ -352,7 +349,7 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool
return false; return false;
} }
// [RH] Lee Killough's changes for silent teleporters from BOOM // [RH] Lee Killough's changes for silent teleporters from BOOM
if (keepOrientation && line) if ((flags & TELF_KEEPORIENTATION) && line)
{ {
// Get the angle between the exit thing and source linedef. // Get the angle between the exit thing and source linedef.
// Rotate 90 degrees, so that walking perpendicularly across // Rotate 90 degrees, so that walking perpendicularly across
@ -382,10 +379,10 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool
{ {
badangle = 1 << ANGLETOFINESHIFT; badangle = 1 << ANGLETOFINESHIFT;
} }
if (P_Teleport (thing, searcher->X(), searcher->Y(), z, searcher->angle + badangle, fog, sourceFog, keepOrientation, haltVelocity, keepHeight)) if (P_Teleport (thing, searcher->X(), searcher->Y(), z, searcher->angle + badangle, flags))
{ {
// [RH] Lee Killough's changes for silent teleporters from BOOM // [RH] Lee Killough's changes for silent teleporters from BOOM
if (!fog && line && keepOrientation) if (!(flags & TELF_DESTFOG) && line && (flags & TELF_KEEPORIENTATION))
{ {
// Rotate thing according to difference in angles // Rotate thing according to difference in angles
thing->angle += angle; thing->angle += angle;
@ -601,7 +598,8 @@ bool EV_TeleportOther (int other_tid, int dest_tid, bool fog)
while ( (victim = iterator.Next ()) ) while ( (victim = iterator.Next ()) )
{ {
didSomething |= EV_Teleport (dest_tid, 0, NULL, 0, victim, fog, fog, !fog); didSomething |= EV_Teleport (dest_tid, 0, NULL, 0, victim,
fog ? (TELF_DESTFOG | TELF_SOURCEFOG) : TELF_KEEPORIENTATION);
} }
} }
@ -621,7 +619,7 @@ static bool DoGroupForOne (AActor *victim, AActor *source, AActor *dest, bool fl
P_Teleport (victim, dest->X() + newX, P_Teleport (victim, dest->X() + newX,
dest->Y() + newY, dest->Y() + newY,
floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z(), floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z(),
0, fog, fog, !fog); 0, fog ? (TELF_DESTFOG | TELF_SOURCEFOG) : TELF_KEEPORIENTATION);
// P_Teleport only changes angle if fog is true // P_Teleport only changes angle if fog is true
victim->angle = dest->angle + offAngle; victim->angle = dest->angle + offAngle;
@ -689,7 +687,7 @@ bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_t
{ {
didSomething |= didSomething |=
P_Teleport (sourceOrigin, destOrigin->X(), destOrigin->Y(), P_Teleport (sourceOrigin, destOrigin->X(), destOrigin->Y(),
floorz ? ONFLOORZ : destOrigin->Z(), 0, false, false, true); floorz ? ONFLOORZ : destOrigin->Z(), 0, TELF_KEEPORIENTATION);
sourceOrigin->angle = destOrigin->angle; sourceOrigin->angle = destOrigin->angle;
} }

View File

@ -541,7 +541,7 @@ void R_AddLine (seg_t *line)
if (WallC.Init(tx1, ty1, tx2, ty2, 32)) if (WallC.Init(tx1, ty1, tx2, ty2, 32))
return; return;
if (WallC.sx1 > WindowRight || WallC.sx2 < WindowLeft) if (WallC.sx1 >= WindowRight || WallC.sx2 <= WindowLeft)
return; return;
if (line->linedef == NULL) if (line->linedef == NULL)

View File

@ -667,10 +667,10 @@ void R_EnterMirror (drawseg_t *ds, int depth)
ActiveWallMirror = ds->curline; ActiveWallMirror = ds->curline;
R_ClearPlanes (false); R_ClearPlanes (false);
R_ClearClipSegs (ds->x1, ds->x2 + 1); R_ClearClipSegs (ds->x1, ds->x2);
memcpy (ceilingclip + ds->x1, openings + ds->sprtopclip, (ds->x2 - ds->x1 + 1)*sizeof(*ceilingclip)); memcpy (ceilingclip + ds->x1, openings + ds->sprtopclip, (ds->x2 - ds->x1)*sizeof(*ceilingclip));
memcpy (floorclip + ds->x1, openings + ds->sprbottomclip, (ds->x2 - ds->x1 + 1)*sizeof(*floorclip)); memcpy (floorclip + ds->x1, openings + ds->sprbottomclip, (ds->x2 - ds->x1)*sizeof(*floorclip));
WindowLeft = ds->x1; WindowLeft = ds->x1;
WindowRight = ds->x2; WindowRight = ds->x2;
@ -777,7 +777,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
} }
WindowLeft = 0; WindowLeft = 0;
WindowRight = viewwidth - 1; WindowRight = viewwidth;
MirrorFlags = 0; MirrorFlags = 0;
ActiveWallMirror = NULL; ActiveWallMirror = NULL;

View File

@ -708,8 +708,8 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
check->colormap = basecolormap; // [RH] Save colormap check->colormap = basecolormap; // [RH] Save colormap
check->sky = sky; check->sky = sky;
check->skybox = skybox; check->skybox = skybox;
check->minx = viewwidth; // Was SCREENWIDTH -- killough 11/98 check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
check->maxx = -1; check->right = 0;
check->extralight = stacked_extralight; check->extralight = stacked_extralight;
check->visibility = stacked_visibility; check->visibility = stacked_visibility;
check->viewx = stacked_viewx; check->viewx = stacked_viewx;
@ -740,38 +740,38 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
int x; int x;
assert (start >= 0 && start < viewwidth); assert (start >= 0 && start < viewwidth);
assert (stop >= start && stop < viewwidth); assert (stop > start && stop <= viewwidth);
if (start < pl->minx) if (start < pl->left)
{ {
intrl = pl->minx; intrl = pl->left;
unionl = start; unionl = start;
} }
else else
{ {
unionl = pl->minx; unionl = pl->left;
intrl = start; intrl = start;
} }
if (stop > pl->maxx) if (stop > pl->right)
{ {
intrh = pl->maxx; intrh = pl->right;
unionh = stop; unionh = stop;
} }
else else
{ {
unionh = pl->maxx; unionh = pl->right;
intrh = stop; intrh = stop;
} }
for (x = intrl; x <= intrh && pl->top[x] == 0x7fff; x++) for (x = intrl; x < intrh && pl->top[x] == 0x7fff; x++)
; ;
if (x > intrh) if (x >= intrh)
{ {
// use the same visplane // use the same visplane
pl->minx = unionl; pl->left = unionl;
pl->maxx = unionh; pl->right = unionh;
} }
else else
{ {
@ -811,8 +811,8 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
new_pl->MirrorFlags = pl->MirrorFlags; new_pl->MirrorFlags = pl->MirrorFlags;
new_pl->CurrentSkybox = pl->CurrentSkybox; new_pl->CurrentSkybox = pl->CurrentSkybox;
pl = new_pl; pl = new_pl;
pl->minx = start; pl->left = start;
pl->maxx = stop; pl->right = stop;
clearbufshort (pl->top, viewwidth, 0x7fff); clearbufshort (pl->top, viewwidth, 0x7fff);
} }
return pl; return pl;
@ -922,23 +922,23 @@ static void R_DrawSky (visplane_t *pl)
{ {
int x; int x;
if (pl->minx > pl->maxx) if (pl->left >= pl->right)
return; return;
dc_iscale = skyiscale; dc_iscale = skyiscale;
clearbuf (swall+pl->minx, pl->maxx-pl->minx+1, dc_iscale<<2); clearbuf (swall+pl->left, pl->right-pl->left, dc_iscale<<2);
if (MirrorFlags & RF_XFLIP) if (MirrorFlags & RF_XFLIP)
{ {
for (x = pl->minx; x <= pl->maxx; ++x) for (x = pl->left; x < pl->right; ++x)
{ {
lwall[x] = (viewwidth - x) << FRACBITS; lwall[x] = (viewwidth - x) << FRACBITS;
} }
} }
else else
{ {
for (x = pl->minx; x <= pl->maxx; ++x) for (x = pl->left; x < pl->right; ++x)
{ {
lwall[x] = x << FRACBITS; lwall[x] = x << FRACBITS;
} }
@ -961,7 +961,7 @@ static void R_DrawSky (visplane_t *pl)
{ {
lastskycol[x] = 0xffffffff; lastskycol[x] = 0xffffffff;
} }
wallscan (pl->minx, pl->maxx, (short *)pl->top, (short *)pl->bottom, swall, lwall, wallscan (pl->left, pl->right, (short *)pl->top, (short *)pl->bottom, swall, lwall,
frontyScale, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); frontyScale, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns);
} }
else else
@ -1001,7 +1001,7 @@ static void R_DrawSkyStriped (visplane_t *pl)
while (yl < viewheight) while (yl < viewheight)
{ {
for (x = pl->minx; x <= pl->maxx; ++x) for (x = pl->left; x < pl->right; ++x)
{ {
top[x] = MAX (yl, (short)pl->top[x]); top[x] = MAX (yl, (short)pl->top[x]);
bot[x] = MIN (yh, (short)pl->bottom[x]); bot[x] = MIN (yh, (short)pl->bottom[x]);
@ -1010,7 +1010,7 @@ static void R_DrawSkyStriped (visplane_t *pl)
{ {
lastskycol[x] = 0xffffffff; lastskycol[x] = 0xffffffff;
} }
wallscan (pl->minx, pl->maxx, top, bot, swall, lwall, rw_pic->yScale, wallscan (pl->left, pl->right, top, bot, swall, lwall, rw_pic->yScale,
backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns);
yl = yh; yl = yh;
yh += drawheight; yh += drawheight;
@ -1094,7 +1094,7 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
{ {
// pl->angle = pa<<ANGLETOFINESHIFT; // pl->angle = pa<<ANGLETOFINESHIFT;
if (pl->minx > pl->maxx) if (pl->left >= pl->right)
return; return;
if (r_drawflat) if (r_drawflat)
@ -1205,7 +1205,7 @@ void R_DrawSkyBoxes ()
visplanes[MAXVISPLANES] = pl->next; visplanes[MAXVISPLANES] = pl->next;
pl->next = NULL; pl->next = NULL;
if (pl->maxx < pl->minx || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES) if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES)
{ {
R_DrawSinglePlane (pl, OPAQUE, false, false); R_DrawSinglePlane (pl, OPAQUE, false, false);
*freehead = pl; *freehead = pl;
@ -1250,11 +1250,11 @@ void R_DrawSkyBoxes ()
validcount++; // Make sure we see all sprites validcount++; // Make sure we see all sprites
R_ClearPlanes (false); R_ClearPlanes (false);
R_ClearClipSegs (pl->minx, pl->maxx + 1); R_ClearClipSegs (pl->left, pl->right);
WindowLeft = pl->minx; WindowLeft = pl->left;
WindowRight = pl->maxx; WindowRight = pl->right;
for (i = pl->minx; i <= pl->maxx; i++) for (i = pl->left; i < pl->right; i++)
{ {
if (pl->top[i] == 0x7fff) if (pl->top[i] == 0x7fff)
{ {
@ -1274,16 +1274,16 @@ void R_DrawSkyBoxes ()
ds_p->siz2 = INT_MAX; ds_p->siz2 = INT_MAX;
ds_p->sz1 = 0; ds_p->sz1 = 0;
ds_p->sz2 = 0; ds_p->sz2 = 0;
ds_p->x1 = pl->minx; ds_p->x1 = pl->left;
ds_p->x2 = pl->maxx; ds_p->x2 = pl->right;
ds_p->silhouette = SIL_BOTH; ds_p->silhouette = SIL_BOTH;
ds_p->sprbottomclip = R_NewOpening (pl->maxx - pl->minx + 1); ds_p->sprbottomclip = R_NewOpening (pl->right - pl->left);
ds_p->sprtopclip = R_NewOpening (pl->maxx - pl->minx + 1); ds_p->sprtopclip = R_NewOpening (pl->right - pl->left);
ds_p->maskedtexturecol = ds_p->swall = -1; ds_p->maskedtexturecol = ds_p->swall = -1;
ds_p->bFogBoundary = false; ds_p->bFogBoundary = false;
ds_p->fake = 0; ds_p->fake = 0;
memcpy (openings + ds_p->sprbottomclip, floorclip + pl->minx, (pl->maxx - pl->minx + 1)*sizeof(short)); memcpy (openings + ds_p->sprbottomclip, floorclip + pl->left, (pl->right - pl->left)*sizeof(short));
memcpy (openings + ds_p->sprtopclip, ceilingclip + pl->minx, (pl->maxx - pl->minx + 1)*sizeof(short)); memcpy (openings + ds_p->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left)*sizeof(short));
firstvissprite = vissprite_p; firstvissprite = vissprite_p;
firstdrawseg = ds_p++; firstdrawseg = ds_p++;
@ -1542,7 +1542,7 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
ystepscale = (DWORD)(-(SDWORD)ystepscale); ystepscale = (DWORD)(-(SDWORD)ystepscale);
} }
int x = pl->maxx - halfviewwidth; int x = pl->right - halfviewwidth - 1;
planeang = (planeang + (ANG90 >> ANGLETOFINESHIFT)) & FINEMASK; planeang = (planeang + (ANG90 >> ANGLETOFINESHIFT)) & FINEMASK;
basexfrac = FixedMul (xscale, finecosine[planeang]) + x*xstepscale; basexfrac = FixedMul (xscale, finecosine[planeang]) + x*xstepscale;
baseyfrac = FixedMul (yscale, -finesine[planeang]) + x*ystepscale; baseyfrac = FixedMul (yscale, -finesine[planeang]) + x*ystepscale;
@ -1742,7 +1742,7 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1)) void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
{ {
int x = pl->maxx; int x = pl->right - 1;
int t2 = pl->top[x]; int t2 = pl->top[x];
int b2 = pl->bottom[x]; int b2 = pl->bottom[x];
@ -1751,7 +1751,7 @@ void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
clearbufshort (spanend+t2, b2-t2, x); clearbufshort (spanend+t2, b2-t2, x);
} }
for (--x; x >= pl->minx; --x) for (--x; x >= pl->left; --x)
{ {
int t1 = pl->top[x]; int t1 = pl->top[x];
int b1 = pl->bottom[x]; int b1 = pl->bottom[x];
@ -1790,7 +1790,7 @@ void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
// Draw any spans that are still open // Draw any spans that are still open
while (t2 < b2) while (t2 < b2)
{ {
mapfunc (--b2, pl->minx); mapfunc (--b2, pl->left);
} }
} }

View File

@ -38,7 +38,7 @@ struct visplane_s
FTextureID picnum; FTextureID picnum;
int lightlevel; int lightlevel;
fixed_t xoffs, yoffs; // killough 2/28/98: Support scrolling flats fixed_t xoffs, yoffs; // killough 2/28/98: Support scrolling flats
int minx, maxx; int left, right;
FDynamicColormap *colormap; // [RH] Support multiple colormaps FDynamicColormap *colormap; // [RH] Support multiple colormaps
fixed_t xscale, yscale; // [RH] Support flat scaling fixed_t xscale, yscale; // [RH] Support flat scaling
angle_t angle; // [RH] Support flat rotation angle_t angle; // [RH] Support flat rotation

View File

@ -206,13 +206,13 @@ void ClipMidtex(int x1, int x2)
short most[MAXWIDTH]; short most[MAXWIDTH];
WallMost(most, curline->frontsector->ceilingplane, &WallC); WallMost(most, curline->frontsector->ceilingplane, &WallC);
for (int i = x1; i <= x2; ++i) for (int i = x1; i < x2; ++i)
{ {
if (wallupper[i] < most[i]) if (wallupper[i] < most[i])
wallupper[i] = most[i]; wallupper[i] = most[i];
} }
WallMost(most, curline->frontsector->floorplane, &WallC); WallMost(most, curline->frontsector->floorplane, &WallC);
for (int i = x1; i <= x2; ++i) for (int i = x1; i < x2; ++i)
{ {
if (walllower[i] > most[i]) if (walllower[i] > most[i])
walllower[i] = most[i]; walllower[i] = most[i];
@ -398,12 +398,12 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
OWallMost(walllower, textop - texheight, &WallC); OWallMost(walllower, textop - texheight, &WallC);
} }
for (i = x1; i <= x2; i++) for (i = x1; i < x2; i++)
{ {
if (wallupper[i] < mceilingclip[i]) if (wallupper[i] < mceilingclip[i])
wallupper[i] = mceilingclip[i]; wallupper[i] = mceilingclip[i];
} }
for (i = x1; i <= x2; i++) for (i = x1; i < x2; i++)
{ {
if (walllower[i] > mfloorclip[i]) if (walllower[i] > mfloorclip[i])
walllower[i] = mfloorclip[i]; walllower[i] = mfloorclip[i];
@ -426,7 +426,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
// draw the columns one at a time // draw the columns one at a time
if (drawmode == DoDraw0) if (drawmode == DoDraw0)
{ {
for (dc_x = x1; dc_x <= x2; ++dc_x) for (dc_x = x1; dc_x < x2; ++dc_x)
{ {
BlastMaskedColumn (R_DrawMaskedColumn, tex); BlastMaskedColumn (R_DrawMaskedColumn, tex);
} }
@ -434,9 +434,9 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
else else
{ {
// [RH] Draw up to four columns at once // [RH] Draw up to four columns at once
int stop = (x2+1) & ~3; int stop = x2 & ~3;
if (x1 > x2) if (x1 >= x2)
goto clearfog; goto clearfog;
dc_x = x1; dc_x = x1;
@ -458,7 +458,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
dc_x++; dc_x++;
} }
while (dc_x <= x2) while (dc_x < x2)
{ {
BlastMaskedColumn (R_DrawMaskedColumn, tex); BlastMaskedColumn (R_DrawMaskedColumn, tex);
dc_x++; dc_x++;
@ -486,7 +486,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
if (fake3D & FAKE3D_CLIPTOP) if (fake3D & FAKE3D_CLIPTOP)
{ {
OWallMost(wallupper, sclipTop - viewz, &WallC); OWallMost(wallupper, sclipTop - viewz, &WallC);
for (i = x1; i <= x2; i++) for (i = x1; i < x2; i++)
{ {
if (wallupper[i] < mceilingclip[i]) if (wallupper[i] < mceilingclip[i])
wallupper[i] = mceilingclip[i]; wallupper[i] = mceilingclip[i];
@ -496,7 +496,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
if (fake3D & FAKE3D_CLIPBOTTOM) if (fake3D & FAKE3D_CLIPBOTTOM)
{ {
OWallMost(walllower, sclipBottom - viewz, &WallC); OWallMost(walllower, sclipBottom - viewz, &WallC);
for (i = x1; i <= x2; i++) for (i = x1; i < x2; i++)
{ {
if (walllower[i] > mfloorclip[i]) if (walllower[i] > mfloorclip[i])
walllower[i] = mfloorclip[i]; walllower[i] = mfloorclip[i];
@ -520,11 +520,11 @@ clearfog:
if (fake3D & FAKE3D_REFRESHCLIP) if (fake3D & FAKE3D_REFRESHCLIP)
{ {
assert(ds->bkup >= 0); assert(ds->bkup >= 0);
memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2-ds->x1+1) * 2); memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2 - ds->x1) * 2);
} }
else else
{ {
clearbufshort(openings + ds->sprtopclip - ds->x1 + x1, x2-x1+1, viewheight); clearbufshort(openings + ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
} }
} }
return; return;
@ -539,7 +539,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255); fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255);
ESPSResult drawmode; ESPSResult drawmode;
drawmode = R_SetPatchStyle (LegacyRenderStyles[rover->flags & FF_ADDITIVETRANS ? STYLE_Add : STYLE_Translucent], drawmode = R_SetPatchStyle (LegacyRenderStyles[rover->flags & FF_ADDITIVETRANS ? STYLE_Add : STYLE_Translucent],
Alpha, 0, 0); Alpha, 0, 0);
if(drawmode == DontDraw) { if(drawmode == DontDraw) {
R_FinishSetPatchStyle(); R_FinishSetPatchStyle();
@ -617,12 +617,12 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
OWallMost(wallupper, sclipTop - viewz, &WallC); OWallMost(wallupper, sclipTop - viewz, &WallC);
OWallMost(walllower, sclipBottom - viewz, &WallC); OWallMost(walllower, sclipBottom - viewz, &WallC);
for (i = x1; i <= x2; i++) for (i = x1; i < x2; i++)
{ {
if (wallupper[i] < mceilingclip[i]) if (wallupper[i] < mceilingclip[i])
wallupper[i] = mceilingclip[i]; wallupper[i] = mceilingclip[i];
} }
for (i = x1; i <= x2; i++) for (i = x1; i < x2; i++)
{ {
if (walllower[i] > mfloorclip[i]) if (walllower[i] > mfloorclip[i])
walllower[i] = mfloorclip[i]; walllower[i] = mfloorclip[i];
@ -1093,7 +1093,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
palookupoffse[3] = dc_colormap; palookupoffse[3] = dc_colormap;
} }
for(; (x <= x2) && (x & 3); ++x) for(; (x < x2) && (x & 3); ++x)
{ {
light += rw_lightstep; light += rw_lightstep;
y1ve[0] = uwal[x];//max(uwal[x],umost[x]); y1ve[0] = uwal[x];//max(uwal[x],umost[x]);
@ -1116,7 +1116,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
dovline1(); dovline1();
} }
for(; x <= x2-3; x += 4) for(; x < x2-3; x += 4)
{ {
bad = 0; bad = 0;
for (z = 3; z>= 0; --z) for (z = 3; z>= 0; --z)
@ -1186,7 +1186,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
} }
} }
} }
for(;x<=x2;x++) for(;x<x2;x++)
{ {
light += rw_lightstep; light += rw_lightstep;
y1ve[0] = uwal[x];//max(uwal[x],umost[x]); y1ve[0] = uwal[x];//max(uwal[x],umost[x]);
@ -1227,7 +1227,7 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
down = most1; down = most1;
assert(WallC.sx1 <= x1); assert(WallC.sx1 <= x1);
assert(WallC.sx2 > x2); assert(WallC.sx2 >= x2);
// kg3D - fake floors instead of zdoom light list // kg3D - fake floors instead of zdoom light list
for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++)
@ -1235,7 +1235,7 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane, &WallC); int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane, &WallC);
if (j != 3) if (j != 3)
{ {
for (int j = x1; j <= x2; ++j) for (int j = x1; j < x2; ++j)
{ {
down[j] = clamp (most3[j], up[j], dwal[j]); down[j] = clamp (most3[j], up[j], dwal[j]);
} }
@ -1317,7 +1317,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed
int j = OWallMost(most3, partition - viewz, &WallC); int j = OWallMost(most3, partition - viewz, &WallC);
if (j != 3) if (j != 3)
{ {
for (int j = x1; j <= x2; ++j) for (int j = x1; j < x2; ++j)
{ {
down[j] = clamp(most3[j], up[j], dwal[j]); down[j] = clamp(most3[j], up[j], dwal[j]);
} }
@ -1341,7 +1341,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed
int j = OWallMost(most3, partition - viewz, &WallC); int j = OWallMost(most3, partition - viewz, &WallC);
if (j != 12) if (j != 12)
{ {
for (int j = x1; j <= x2; ++j) for (int j = x1; j < x2; ++j)
{ {
up[j] = clamp(most3[j], uwal[j], down[j]); up[j] = clamp(most3[j], uwal[j], down[j]);
} }
@ -1460,7 +1460,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe
domvline1(); domvline1();
} }
for(; x <= x2-3; x += 4, p+= 4) for(; x < x2-3; x += 4, p+= 4)
{ {
bad = 0; bad = 0;
for (z = 3, dax = x+3; z >= 0; --z, --dax) for (z = 3, dax = x+3; z >= 0; --z, --dax)
@ -1528,7 +1528,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe
} }
} }
} }
for(; x <= x2; ++x, ++p) for(; x < x2; ++x, ++p)
{ {
light += rw_lightstep; light += rw_lightstep;
y1ve[0] = uwal[x]; y1ve[0] = uwal[x];
@ -1612,7 +1612,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
palookupoffse[3] = dc_colormap; palookupoffse[3] = dc_colormap;
} }
for(; (x <= x2) && ((size_t)p & 3); ++x, ++p) for(; (x < x2) && ((size_t)p & 3); ++x, ++p)
{ {
light += rw_lightstep; light += rw_lightstep;
y1ve[0] = uwal[x];//max(uwal[x],umost[x]); y1ve[0] = uwal[x];//max(uwal[x],umost[x]);
@ -1633,7 +1633,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
tmvline1(); tmvline1();
} }
for(; x <= x2-3; x += 4, p+= 4) for(; x < x2-3; x += 4, p+= 4)
{ {
bad = 0; bad = 0;
for (z = 3, dax = x+3; z >= 0; --z, --dax) for (z = 3, dax = x+3; z >= 0; --z, --dax)
@ -1704,7 +1704,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
} }
} }
} }
for(; x <= x2; ++x, ++p) for(; x < x2; ++x, ++p)
{ {
light += rw_lightstep; light += rw_lightstep;
y1ve[0] = uwal[x]; y1ve[0] = uwal[x];
@ -1855,11 +1855,11 @@ void R_RenderSegLoop ()
} }
if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits)
{ {
wallscan_np2(x1, x2-1, walltop, wallbottom, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false); wallscan_np2(x1, x2, walltop, wallbottom, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false);
} }
else else
{ {
call_wallscan(x1, x2-1, walltop, wallbottom, swall, lwall, yscale, false); call_wallscan(x1, x2, walltop, wallbottom, swall, lwall, yscale, false);
} }
} }
clearbufshort (ceilingclip+x1, x2-x1, viewheight); clearbufshort (ceilingclip+x1, x2-x1, viewheight);
@ -1898,11 +1898,11 @@ void R_RenderSegLoop ()
} }
if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits)
{ {
wallscan_np2(x1, x2-1, walltop, wallupper, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false); wallscan_np2(x1, x2, walltop, wallupper, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false);
} }
else else
{ {
call_wallscan(x1, x2-1, walltop, wallupper, swall, lwall, yscale, false); call_wallscan(x1, x2, walltop, wallupper, swall, lwall, yscale, false);
} }
} }
memcpy (ceilingclip+x1, wallupper+x1, (x2-x1)*sizeof(short)); memcpy (ceilingclip+x1, wallupper+x1, (x2-x1)*sizeof(short));
@ -1944,11 +1944,11 @@ void R_RenderSegLoop ()
} }
if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits)
{ {
wallscan_np2(x1, x2-1, walllower, wallbottom, swall, lwall, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false); wallscan_np2(x1, x2, walllower, wallbottom, swall, lwall, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false);
} }
else else
{ {
call_wallscan(x1, x2-1, walllower, wallbottom, swall, lwall, yscale, false); call_wallscan(x1, x2, walllower, wallbottom, swall, lwall, yscale, false);
} }
} }
memcpy (floorclip+x1, walllower+x1, (x2-x1)*sizeof(short)); memcpy (floorclip+x1, walllower+x1, (x2-x1)*sizeof(short));
@ -2368,7 +2368,7 @@ void R_StoreWallRange (int start, int stop)
ds_p->siz1 = (DWORD)DivScale32 (1, WallC.sz1) >> 1; ds_p->siz1 = (DWORD)DivScale32 (1, WallC.sz1) >> 1;
ds_p->siz2 = (DWORD)DivScale32 (1, WallC.sz2) >> 1; ds_p->siz2 = (DWORD)DivScale32 (1, WallC.sz2) >> 1;
ds_p->x1 = rw_x = start; ds_p->x1 = rw_x = start;
ds_p->x2 = stop-1; ds_p->x2 = stop;
ds_p->curline = curline; ds_p->curline = curline;
rw_stopx = stop; rw_stopx = stop;
ds_p->bFogBoundary = false; ds_p->bFogBoundary = false;
@ -2547,7 +2547,7 @@ void R_StoreWallRange (int start, int stop)
{ {
if (ceilingplane) if (ceilingplane)
{ // killough 4/11/98: add NULL ptr checks { // killough 4/11/98: add NULL ptr checks
ceilingplane = R_CheckPlane (ceilingplane, start, stop-1); ceilingplane = R_CheckPlane (ceilingplane, start, stop);
} }
else else
{ {
@ -2559,7 +2559,7 @@ void R_StoreWallRange (int start, int stop)
{ {
if (floorplane) if (floorplane)
{ // killough 4/11/98: add NULL ptr checks { // killough 4/11/98: add NULL ptr checks
floorplane = R_CheckPlane (floorplane, start, stop-1); floorplane = R_CheckPlane (floorplane, start, stop);
} }
else else
{ {
@ -2707,8 +2707,8 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc)
#endif #endif
if (mostbuf[ix1] < 0) mostbuf[ix1] = 0; if (mostbuf[ix1] < 0) mostbuf[ix1] = 0;
else if (mostbuf[ix1] > viewheight) mostbuf[ix1] = (short)viewheight; else if (mostbuf[ix1] > viewheight) mostbuf[ix1] = (short)viewheight;
if (mostbuf[ix2] < 0) mostbuf[ix2] = 0; if (mostbuf[ix2-1] < 0) mostbuf[ix2-1] = 0;
else if (mostbuf[ix2] > viewheight) mostbuf[ix2] = (short)viewheight; else if (mostbuf[ix2-1] > viewheight) mostbuf[ix2-1] = (short)viewheight;
return bad; return bad;
} }
@ -2865,8 +2865,8 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
if (mostbuf[ix1] < 0) mostbuf[ix1] = 0; if (mostbuf[ix1] < 0) mostbuf[ix1] = 0;
else if (mostbuf[ix1] > viewheight) mostbuf[ix1] = (short)viewheight; else if (mostbuf[ix1] > viewheight) mostbuf[ix1] = (short)viewheight;
if (mostbuf[ix2] < 0) mostbuf[ix2] = 0; if (mostbuf[ix2-1] < 0) mostbuf[ix2-1] = 0;
else if (mostbuf[ix2] > viewheight) mostbuf[ix2] = (short)viewheight; else if (mostbuf[ix2-1] > viewheight) mostbuf[ix2-1] = (short)viewheight;
return bad; return bad;
} }
@ -3063,7 +3063,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
x1 = WallC.sx1; x1 = WallC.sx1;
x2 = WallC.sx2; x2 = WallC.sx2;
if (x1 > clipper->x2 || x2 <= clipper->x1) if (x1 >= clipper->x2 || x2 <= clipper->x1)
goto done; goto done;
WallT.InitFromWallCoords(&WallC); WallT.InitFromWallCoords(&WallC);
@ -3126,14 +3126,8 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
dc_texturemid = topoff + FixedDiv (zpos - viewz, yscale); dc_texturemid = topoff + FixedDiv (zpos - viewz, yscale);
// Clip sprite to drawseg // Clip sprite to drawseg
if (x1 < clipper->x1) x1 = MAX<int>(clipper->x1, x1);
{ x2 = MIN<int>(clipper->x2, x2);
x1 = clipper->x1;
}
if (x2 > clipper->x2)
{
x2 = clipper->x2 + 1;
}
if (x1 >= x2) if (x1 >= x2)
{ {
goto done; goto done;

View File

@ -352,7 +352,7 @@ void R_DrawVisSprite (vissprite_t *vis)
else // DoDraw1 else // DoDraw1
{ {
// Up to four columns at a time // Up to four columns at a time
stop4 = (vis->x2 + 1) & ~3; stop4 = vis->x2 & ~3;
} }
tex = vis->pic; tex = vis->pic;
@ -366,7 +366,7 @@ void R_DrawVisSprite (vissprite_t *vis)
sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale); sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale);
dc_x = vis->x1; dc_x = vis->x1;
x2 = vis->x2 + 1; x2 = vis->x2;
if (dc_x < x2) if (dc_x < x2)
{ {
@ -412,7 +412,7 @@ void R_DrawWallSprite(vissprite_t *spr)
fixed_t yscale; fixed_t yscale;
x1 = MAX<int>(spr->x1, spr->wallc.sx1); x1 = MAX<int>(spr->x1, spr->wallc.sx1);
x2 = MIN<int>(spr->x2 + 1, spr->wallc.sx2 + 1); x2 = MIN<int>(spr->x2, spr->wallc.sx2);
if (x1 >= x2) if (x1 >= x2)
return; return;
WallT.InitFromWallCoords(&spr->wallc); WallT.InitFromWallCoords(&spr->wallc);
@ -868,7 +868,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
x1 = centerx + MulScale32 (tx, xscale); x1 = centerx + MulScale32 (tx, xscale);
// off the right side? // off the right side?
if (x1 > WindowRight) if (x1 >= WindowRight)
return; return;
tx += tex->GetWidth() * thingxscalemul; tx += tex->GetWidth() * thingxscalemul;
@ -880,7 +880,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
xscale = FixedDiv(FixedMul(spritescaleX, xscale), tex->xScale); xscale = FixedDiv(FixedMul(spritescaleX, xscale), tex->xScale);
iscale = (tex->GetWidth() << FRACBITS) / (x2 - x1); iscale = (tex->GetWidth() << FRACBITS) / (x2 - x1);
x2--;
fixed_t yscale = SafeDivScale16(spritescaleY, tex->yScale); fixed_t yscale = SafeDivScale16(spritescaleY, tex->yScale);
@ -1062,7 +1061,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f
if (wallc.Init(lx1, ly1, lx2, ly2, TOO_CLOSE_Z)) if (wallc.Init(lx1, ly1, lx2, ly2, TOO_CLOSE_Z))
return; return;
if (wallc.sx1 > WindowRight || wallc.sx2 <= WindowLeft) if (wallc.sx1 >= WindowRight || wallc.sx2 <= WindowLeft)
return; return;
// Sprite sorting should probably treat these as walls, not sprites, // Sprite sorting should probably treat these as walls, not sprites,
@ -1076,7 +1075,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1; vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1;
vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2-1; vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2;
vis->yscale = yscale; vis->yscale = yscale;
vis->idepth = (unsigned)DivScale32(1, tz) >> 1; vis->idepth = (unsigned)DivScale32(1, tz) >> 1;
vis->depth = tz; vis->depth = tz;
@ -1213,10 +1212,10 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_
return; return;
tx += tex->GetScaledWidth() << FRACBITS; tx += tex->GetScaledWidth() << FRACBITS;
x2 = ((centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS) - 1; x2 = ((centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS);
// off the left side // off the left side
if (x2 < 0) if (x2 <= 0)
return; return;
// store information in a vissprite // store information in a vissprite
@ -1255,7 +1254,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_
vis->texturemid -= BaseRatioSizes[WidescreenRatio][2]; vis->texturemid -= BaseRatioSizes[WidescreenRatio][2];
} }
vis->x1 = x1 < 0 ? 0 : x1; vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; vis->x2 = x2 >= viewwidth ? viewwidth : x2;
vis->xscale = DivScale16(pspritexscale, tex->xScale); vis->xscale = DivScale16(pspritexscale, tex->xScale);
vis->yscale = DivScale16(pspriteyscale, tex->yScale); vis->yscale = DivScale16(pspriteyscale, tex->yScale);
vis->Translation = 0; // [RH] Use default colors vis->Translation = 0; // [RH] Use default colors
@ -1807,7 +1806,7 @@ void R_DrawSprite (vissprite_t *spr)
x2 = spr->x2; x2 = spr->x2;
// [RH] Quickly reject sprites with bad x ranges. // [RH] Quickly reject sprites with bad x ranges.
if (x1 > x2) if (x1 >= x2)
return; return;
// [RH] Sprites split behind a one-sided line can also be discarded. // [RH] Sprites split behind a one-sided line can also be discarded.
@ -2050,7 +2049,7 @@ void R_DrawSprite (vissprite_t *spr)
return; return;
} }
i = x2 - x1 + 1; i = x2 - x1;
clip1 = clipbot + x1; clip1 = clipbot + x1;
clip2 = cliptop + x1; clip2 = cliptop + x1;
do do
@ -2073,7 +2072,7 @@ void R_DrawSprite (vissprite_t *spr)
// kg3D - no clipping on fake segs // kg3D - no clipping on fake segs
if(ds->fake) continue; if(ds->fake) continue;
// determine if the drawseg obscures the sprite // determine if the drawseg obscures the sprite
if (ds->x1 > x2 || ds->x2 < x1 || if (ds->x1 >= x2 || ds->x2 <= x1 ||
(!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == -1 && (!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == -1 &&
!ds->bFogBoundary) ) !ds->bFogBoundary) )
{ {
@ -2116,7 +2115,7 @@ void R_DrawSprite (vissprite_t *spr)
{ {
clip1 = clipbot + r1; clip1 = clipbot + r1;
clip2 = openings + ds->sprbottomclip + r1 - ds->x1; clip2 = openings + ds->sprbottomclip + r1 - ds->x1;
i = r2 - r1 + 1; i = r2 - r1;
do do
{ {
if (*clip1 > *clip2) if (*clip1 > *clip2)
@ -2130,7 +2129,7 @@ void R_DrawSprite (vissprite_t *spr)
{ {
clip1 = cliptop + r1; clip1 = cliptop + r1;
clip2 = openings + ds->sprtopclip + r1 - ds->x1; clip2 = openings + ds->sprtopclip + r1 - ds->x1;
i = r2 - r1 + 1; i = r2 - r1;
do do
{ {
if (*clip1 < *clip2) if (*clip1 < *clip2)
@ -2182,7 +2181,7 @@ void R_DrawSprite (vissprite_t *spr)
} }
if (x2 < viewwidth - 1) if (x2 < viewwidth - 1)
{ {
clearbufshort(cliptop + x2 + 1, viewwidth - x2 - 1, viewheight); clearbufshort(cliptop + x2, viewwidth - x2, viewheight);
} }
int minvoxely = spr->gzt <= hzt ? 0 : (spr->gzt - hzt) / spr->yscale; int minvoxely = spr->gzt <= hzt ? 0 : (spr->gzt - hzt) / spr->yscale;
int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale; int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale;
@ -2459,13 +2458,13 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
drawseg_t *ds = &drawsegs[InterestingDrawsegs[p]]; drawseg_t *ds = &drawsegs[InterestingDrawsegs[p]];
// kg3D - no fake segs // kg3D - no fake segs
if(ds->fake) continue; if(ds->fake) continue;
if (ds->x1 >= x2 || ds->x2 < x1) if (ds->x1 >= x2 || ds->x2 <= x1)
{ {
continue; continue;
} }
if (Scale (ds->siz2 - ds->siz1, (x2 + x1)/2 - ds->sx1, ds->sx2 - ds->sx1) + ds->siz1 < vis->idepth) if (Scale (ds->siz2 - ds->siz1, (x2 + x1)/2 - ds->sx1, ds->sx2 - ds->sx1) + ds->siz1 < vis->idepth)
{ {
R_RenderMaskedSegRange (ds, MAX<int> (ds->x1, x1), MIN<int> (ds->x2, x2-1)); R_RenderMaskedSegRange (ds, MAX<int>(ds->x1, x1), MIN<int>(ds->x2, x2));
} }
} }
} }
@ -2480,7 +2479,7 @@ void R_DrawParticle (vissprite_t *vis)
int yl = vis->gzb; int yl = vis->gzb;
int ycount = vis->gzt - yl + 1; int ycount = vis->gzt - yl + 1;
int x1 = vis->x1; int x1 = vis->x1;
int countbase = vis->x2 - x1 + 1; int countbase = vis->x2 - x1;
R_DrawMaskedSegsBehindParticle (vis); R_DrawMaskedSegsBehindParticle (vis);

View File

@ -283,6 +283,7 @@ void I_InitSound ()
if ((!GSnd || !GSnd->IsValid()) && IsOpenALPresent()) if ((!GSnd || !GSnd->IsValid()) && IsOpenALPresent())
{ {
Printf (TEXTCOLOR_RED"FMod Ex Sound init failed. Trying OpenAL.\n"); Printf (TEXTCOLOR_RED"FMod Ex Sound init failed. Trying OpenAL.\n");
I_CloseSound();
GSnd = new OpenALSoundRenderer; GSnd = new OpenALSoundRenderer;
snd_backend = "openal"; snd_backend = "openal";
} }
@ -300,6 +301,7 @@ void I_InitSound ()
if ((!GSnd || !GSnd->IsValid()) && IsFModExPresent()) if ((!GSnd || !GSnd->IsValid()) && IsFModExPresent())
{ {
Printf (TEXTCOLOR_RED"OpenAL Sound init failed. Trying FMod Ex.\n"); Printf (TEXTCOLOR_RED"OpenAL Sound init failed. Trying FMod Ex.\n");
I_CloseSound();
GSnd = new FMODSoundRenderer; GSnd = new FMODSoundRenderer;
snd_backend = "fmod"; snd_backend = "fmod";
} }

View File

@ -4975,6 +4975,133 @@ enum RadiusGiveFlags
RGF_EITHER = 1 << 17, RGF_EITHER = 1 << 17,
}; };
static bool DoRadiusGive(AActor *self, AActor *thing, const PClass *item, int amount, fixed_t distance, int flags, const PClass *filter, FName species, fixed_t mindist)
{
// [MC] We only want to make an exception for missiles here. Nothing else.
bool missilePass = !!((flags & RGF_MISSILES) && thing->isMissile());
if (thing == self)
{
if (!(flags & RGF_GIVESELF))
return false;
}
else if (thing->isMissile())
{
if (!missilePass)
return false;
}
//[MC] Check for a filter, species, and the related exfilter/expecies/either flag(s).
bool filterpass = DoCheckClass(thing, filter, !!(flags & RGF_EXFILTER)),
speciespass = DoCheckSpecies(thing, species, !!(flags & RGF_EXSPECIES));
if ((flags & RGF_EITHER) ? (!(filterpass || speciespass)) : (!(filterpass && speciespass)))
{
if (thing != self) //Don't let filter and species obstruct RGF_GIVESELF.
return false;
}
//Check for target, master, and tracer flagging.
bool targetPass = true;
bool masterPass = true;
bool tracerPass = true;
bool ptrPass = false;
if ((thing != self) && (flags & (RGF_NOTARGET | RGF_NOMASTER | RGF_NOTRACER)))
{
if ((thing == self->target) && (flags & RGF_NOTARGET))
targetPass = false;
if ((thing == self->master) && (flags & RGF_NOMASTER))
masterPass = false;
if ((thing == self->tracer) && (flags & RGF_NOTRACER))
tracerPass = false;
ptrPass = (flags & RGF_INCLUSIVE) ? (targetPass || masterPass || tracerPass) : (targetPass && masterPass && tracerPass);
//We should not care about what the actor is here. It's safe to abort this actor.
if (!ptrPass)
return false;
}
//Next, actor flag checking.
bool selfPass = !!((flags & RGF_GIVESELF) && thing == self);
bool corpsePass = !!((flags & RGF_CORPSES) && thing->flags & MF_CORPSE);
bool killedPass = !!((flags & RGF_KILLED) && thing->flags6 & MF6_KILLED);
bool monsterPass = !!((flags & RGF_MONSTERS) && thing->flags3 & MF3_ISMONSTER);
bool objectPass = !!((flags & RGF_OBJECTS) && (thing->player == NULL) && (!(thing->flags3 & MF3_ISMONSTER))
&& ((thing->flags & MF_SHOOTABLE) || (thing->flags6 & MF6_VULNERABLE)));
bool playerPass = !!((flags & RGF_PLAYERS) && (thing->player != NULL) && (thing->player->mo == thing));
bool voodooPass = !!((flags & RGF_VOODOO) && (thing->player != NULL) && (thing->player->mo != thing));
//Self calls priority over the rest of this.
if (!selfPass)
{
//If it's specifically a monster/object/player/voodoo... Can be either or...
if (monsterPass || objectPass || playerPass || voodooPass)
{
//...and is dead, without desire to give to the dead...
if (((thing->health <= 0) && !(corpsePass || killedPass)))
{
//Skip!
return false;
}
}
}
bool itemPass = !!((flags & RGF_ITEMS) && thing->IsKindOf(RUNTIME_CLASS(AInventory)));
if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass)
{
fixedvec3 diff = self->Vec3To(thing);
diff.z += (thing->height - self->height) / 2;
if (flags & RGF_CUBE)
{ // check if inside a cube
double dx = fabs((double)(diff.x));
double dy = fabs((double)(diff.y));
double dz = fabs((double)(diff.z));
double dist = (double)distance;
double min = (double)mindist;
if ((dx > dist || dy > dist || dz > dist) || (min && (dx < min && dy < min && dz < min)))
{
return false;
}
}
else
{ // check if inside a sphere
double distsquared = double(distance) * double(distance);
double minsquared = double(mindist) * double(mindist);
double lengthsquared = TVector3<double>(diff.x, diff.y, diff.z).LengthSquared();
if (lengthsquared > distsquared || (minsquared && (lengthsquared < minsquared)))
{
return false;
}
}
if ((flags & RGF_NOSIGHT) || P_CheckSight(thing, self, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
{ // OK to give; target is in direct path, or the monster doesn't care about it being in line of sight.
AInventory *gift = static_cast<AInventory *>(Spawn(item, 0, 0, 0, NO_REPLACE));
if (gift->IsKindOf(RUNTIME_CLASS(AHealth)))
{
gift->Amount *= amount;
}
else
{
gift->Amount = amount;
}
gift->flags |= MF_DROPPED;
gift->ClearCounters();
if (!gift->CallTryPickup(thing))
{
gift->Destroy();
return false;
}
else
{
return true;
}
}
}
return false;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
{ {
ACTION_PARAM_START(7); ACTION_PARAM_START(7);
@ -4997,126 +5124,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
{ {
amount = 1; amount = 1;
} }
FBlockThingsIterator it(FBoundingBox(self->X(), self->Y(), distance));
AActor *thing; AActor *thing;
bool given = false; bool given = false;
while ((thing = it.Next())) if (flags & RGF_MISSILES)
{ {
//[MC] Check for a filter, species, and the related exfilter/expecies/either flag(s). TThinkerIterator<AActor> it;
bool filterpass = DoCheckClass(thing, filter, !!(flags & RGF_EXFILTER)), while ((thing = it.Next()))
speciespass = DoCheckSpecies(thing, species, !!(flags & RGF_EXSPECIES));
if ((flags & RGF_EITHER) ? (!(filterpass || speciespass)) : (!(filterpass && speciespass)))
{ {
if (thing != self) //Don't let filter and species obstruct RGF_GIVESELF. if (DoRadiusGive(self, thing, item, amount, distance, flags, filter, species, mindist)) given = true;
continue;
} }
}
if (thing == self) else
{
FBlockThingsIterator it(FBoundingBox(self->X(), self->Y(), distance));
while ((thing = it.Next()))
{ {
if (!(flags & RGF_GIVESELF)) if (DoRadiusGive(self, thing, item, amount, distance, flags, filter, species, mindist)) given = true;
continue;
}
//Check for target, master, and tracer flagging.
bool targetPass = true;
bool masterPass = true;
bool tracerPass = true;
bool ptrPass = false;
if ((thing != self) && (flags & (RGF_NOTARGET | RGF_NOMASTER | RGF_NOTRACER)))
{
if ((thing == self->target) && (flags & RGF_NOTARGET))
targetPass = false;
if ((thing == self->master) && (flags & RGF_NOMASTER))
masterPass = false;
if ((thing == self->tracer) && (flags & RGF_NOTRACER))
tracerPass = false;
ptrPass = (flags & RGF_INCLUSIVE) ? (targetPass || masterPass || tracerPass) : (targetPass && masterPass && tracerPass);
//We should not care about what the actor is here. It's safe to abort this actor.
if (!ptrPass)
continue;
}
//Next, actor flag checking.
bool selfPass = !!((flags & RGF_GIVESELF) && thing == self);
bool corpsePass = !!((flags & RGF_CORPSES) && thing->flags & MF_CORPSE);
bool killedPass = !!((flags & RGF_KILLED) && thing->flags6 & MF6_KILLED);
bool monsterPass = !!((flags & RGF_MONSTERS) && thing->flags3 & MF3_ISMONSTER);
bool objectPass = !!((flags & RGF_OBJECTS) && (thing->player == NULL) && (!(thing->flags3 & MF3_ISMONSTER))
&& ((thing->flags & MF_SHOOTABLE) || (thing->flags6 & MF6_VULNERABLE)));
bool playerPass = !!((flags & RGF_PLAYERS) && (thing->player != NULL) && (thing->player->mo == thing));
bool voodooPass = !!((flags & RGF_VOODOO) && (thing->player != NULL) && (thing->player->mo != thing));
//Self calls priority over the rest of this.
if (!selfPass)
{
//If it's specifically a monster/object/player/voodoo... Can be either or...
if (monsterPass || objectPass || playerPass || voodooPass)
{
//...and is dead, without desire to give to the dead...
if (((thing->health <= 0) && !(corpsePass || killedPass)))
{
//Skip!
continue;
}
}
}
bool itemPass = !!((flags & RGF_ITEMS) && thing->IsKindOf(RUNTIME_CLASS(AInventory)));
bool missilePass = !!((flags & RGF_MISSILES) && thing->flags & MF_MISSILE);
if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass)
{
fixedvec3 diff = self->Vec3To(thing);
diff.z += (thing->height - self->height) / 2;
if (flags & RGF_CUBE)
{ // check if inside a cube
double dx = fabs((double)(diff.x));
double dy = fabs((double)(diff.y));
double dz = fabs((double)(diff.z));
double dist = (double)distance;
double min = (double)mindist;
if ((dx > dist || dy > dist || dz > dist) || (min && (dx < min && dy < min && dz < min)))
{
continue;
}
}
else
{ // check if inside a sphere
double distsquared = double(distance) * double(distance);
double minsquared = double(mindist) * double(mindist);
double lengthsquared = TVector3<double>(diff.x, diff.y, diff.z).LengthSquared();
if (lengthsquared > distsquared || (minsquared && (lengthsquared < minsquared)))
{
continue;
}
}
if ((flags & RGF_NOSIGHT) || P_CheckSight(thing, self, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
{ // OK to give; target is in direct path, or the monster doesn't care about it being in line of sight.
AInventory *gift = static_cast<AInventory *>(Spawn(item, 0, 0, 0, NO_REPLACE));
if (gift->IsKindOf(RUNTIME_CLASS(AHealth)))
{
gift->Amount *= amount;
}
else
{
gift->Amount = amount;
}
gift->flags |= MF_DROPPED;
gift->ClearCounters();
if (!gift->CallTryPickup(thing))
{
gift->Destroy();
}
else
{
given = true;
}
}
} }
} }
ACTION_SET_RESULT(given); ACTION_SET_RESULT(given);

View File

@ -1424,13 +1424,11 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real
*cleany = cy2; *cleany = cy2;
} }
if (*cleanx > 1 && *cleany > 1 && *cleanx != *cleany) if (*cleanx < *cleany)
{ *cleany = *cleanx;
if (*cleanx < *cleany) else
*cleany = *cleanx; *cleanx = *cleany;
else
*cleanx = *cleany;
}
if (_cx1 != NULL) *_cx1 = cx1; if (_cx1 != NULL) *_cx1 = cx1;
if (_cx2 != NULL) *_cx2 = cx2; if (_cx2 != NULL) *_cx2 = cx2;
} }

View File

@ -525,6 +525,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break; break;
case WM_DISPLAYCHANGE: case WM_DISPLAYCHANGE:
case WM_STYLECHANGED:
if (SpawnEAXWindow) if (SpawnEAXWindow)
{ {
SpawnEAXWindow = false; SpawnEAXWindow = false;

View File

@ -364,18 +364,6 @@ OptionValue "Gender"
2, "Other" 2, "Other"
} }
OptionValue "Autoaim"
{
0, "Never"
1, "Very low"
2, "Low"
3, "Medium"
4, "High"
5, "Very high"
6, "Always"
}
ListMenu "PlayerMenu" ListMenu "PlayerMenu"
{ {
StaticTextCentered 160, 6, "$MNU_PLAYERSETUP" StaticTextCentered 160, 6, "$MNU_PLAYERSETUP"
@ -414,7 +402,7 @@ ListMenu "PlayerMenu"
ValueText "Class", "Class" ValueText "Class", "Class"
ValueText "Skin", "Skin" ValueText "Skin", "Skin"
ValueText "Gender", "Gender", "Gender" ValueText "Gender", "Gender", "Gender"
ValueText "Autoaim", "Autoaim", "Autoaim" Slider "Autoaim", "Autoaim", 0, 35, 1
ValueText "Switch on pickup", "Switch", "OffOn" ValueText "Switch on pickup", "Switch", "OffOn"
ValueText "Always Run", "AlwaysRun", "OnOff" ValueText "Always Run", "AlwaysRun", "OnOff"
Class "PlayerMenu" Class "PlayerMenu"
@ -710,6 +698,8 @@ OptionMenu "VideoOptions"
Option "Teleporter zoom", "telezoom", "OnOff" Option "Teleporter zoom", "telezoom", "OnOff"
Slider "Earthquake shake intensity", "r_quakeintensity", 0.0, 1.0, 0.05, 2 Slider "Earthquake shake intensity", "r_quakeintensity", 0.0, 1.0, 0.05, 2
Option "Interpolate monster movement", "nomonsterinterpolation", "NoYes" Option "Interpolate monster movement", "nomonsterinterpolation", "NoYes"
Slider "Menu dim", "dimamount", 0, 1.0, 0.05, 2
ColorPicker "Dim color", "dimcolor"
} }
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------