This commit is contained in:
Christoph Oelckers 2014-08-11 13:18:21 +02:00
commit c30cfb3190
18 changed files with 1136 additions and 1050 deletions

View file

@ -5,6 +5,7 @@
#include "doomtype.h" #include "doomtype.h"
#include "doomdef.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -62,4 +63,25 @@ struct FFileList
void ScanDirectory(TArray<FFileList> &list, const char *dirpath); void ScanDirectory(TArray<FFileList> &list, const char *dirpath);
//==========================================================================
//
// Functions to compensate for a tic being a bit short.
// Since ZDoom uses a milliseconds timer for game timing
// 35 tics are actually only 0.98 seconds.
// For real time display this needs to be adjusted
//
//==========================================================================
inline int AdjustTics(int tics)
{
return (tics * 98) / 100;
}
inline int Tics2Seconds(int tics)
{
return (tics * 98) / (100 * TICRATE);
}
#endif #endif

View file

@ -25,6 +25,11 @@ void ABasicArmor::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType; arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType;
if (SaveVersion >= 4511)
{
arc << ActualSaveAmount;
}
} }
//=========================================================================== //===========================================================================
@ -69,6 +74,7 @@ AInventory *ABasicArmor::CreateCopy (AActor *other)
copy->Icon = Icon; copy->Icon = Icon;
copy->BonusCount = BonusCount; copy->BonusCount = BonusCount;
copy->ArmorType = ArmorType; copy->ArmorType = ArmorType;
copy->ActualSaveAmount = ActualSaveAmount;
GoAwayAndDie (); GoAwayAndDie ();
return copy; return copy;
} }
@ -268,6 +274,7 @@ bool ABasicArmorPickup::Use (bool pickup)
armor->MaxAbsorb = MaxAbsorb; armor->MaxAbsorb = MaxAbsorb;
armor->MaxFullAbsorb = MaxFullAbsorb; armor->MaxFullAbsorb = MaxFullAbsorb;
armor->ArmorType = this->GetClass()->TypeName; armor->ArmorType = this->GetClass()->TypeName;
armor->ActualSaveAmount = SaveAmount;
return true; return true;
} }
@ -360,6 +367,7 @@ bool ABasicArmorBonus::Use (bool pickup)
armor->MaxAbsorb = MaxAbsorb; armor->MaxAbsorb = MaxAbsorb;
armor->ArmorType = this->GetClass()->TypeName; armor->ArmorType = this->GetClass()->TypeName;
armor->MaxFullAbsorb = MaxFullAbsorb; armor->MaxFullAbsorb = MaxFullAbsorb;
armor->ActualSaveAmount = MaxSaveAmount;
} }
armor->Amount = MIN(armor->Amount + saveAmount, MaxSaveAmount + armor->BonusCount); armor->Amount = MIN(armor->Amount + saveAmount, MaxSaveAmount + armor->BonusCount);

View file

@ -423,6 +423,7 @@ public:
int MaxFullAbsorb; int MaxFullAbsorb;
int BonusCount; int BonusCount;
FNameNoInit ArmorType; FNameNoInit ArmorType;
int ActualSaveAmount;
}; };
// BasicArmorPickup replaces the armor you have. // BasicArmorPickup replaces the armor you have.

View file

@ -886,8 +886,11 @@ class CommandDrawString : public SBarInfoCommand
} }
break; break;
case TIME: case TIME:
str.Format("%02d:%02d:%02d", (level.time/TICRATE)/3600, ((level.time/TICRATE)%3600)/60, (level.time/TICRATE)%60); {
int sec = Tics2Seconds(level.time);
str.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60);
break; break;
}
case LOGTEXT: case LOGTEXT:
str = statusBar->CPlayer->LogText; str = statusBar->CPlayer->LogText;
break; break;

View file

@ -867,7 +867,7 @@ static void DrawTime()
: (hud_showtime < 6 : (hud_showtime < 6
? level.time ? level.time
: level.totaltime); : level.totaltime);
const int timeSeconds = timeTicks / TICRATE; const int timeSeconds = Tics2Seconds(timeTicks);
hours = timeSeconds / 3600; hours = timeSeconds / 3600;
minutes = (timeSeconds % 3600) / 60; minutes = (timeSeconds % 3600) / 60;
@ -994,7 +994,7 @@ void DrawHUD()
if (am_showtotaltime) if (am_showtotaltime)
{ {
seconds = level.totaltime / TICRATE; seconds = Tics2Seconds(level.totaltime);
mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60);
DrawHudText(SmallFont, hudcolor_ttim, printstr, hudwidth-length, bottom, FRACUNIT); DrawHudText(SmallFont, hudcolor_ttim, printstr, hudwidth-length, bottom, FRACUNIT);
bottom -= fonth; bottom -= fonth;
@ -1004,14 +1004,14 @@ void DrawHUD()
{ {
if (level.clusterflags&CLUSTER_HUB) if (level.clusterflags&CLUSTER_HUB)
{ {
seconds = level.time /TICRATE; seconds = Tics2Seconds(level.time);
mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60);
DrawHudText(SmallFont, hudcolor_time, printstr, hudwidth-length, bottom, FRACUNIT); DrawHudText(SmallFont, hudcolor_time, printstr, hudwidth-length, bottom, FRACUNIT);
bottom -= fonth; bottom -= fonth;
} }
// Single level time for hubs // Single level time for hubs
seconds= level.maptime /TICRATE; seconds= Tics2Seconds(level.maptime);
mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60);
DrawHudText(SmallFont, hudcolor_ltim, printstr, hudwidth-length, bottom, FRACUNIT); DrawHudText(SmallFont, hudcolor_ltim, printstr, hudwidth-length, bottom, FRACUNIT);
} }

View file

@ -1306,8 +1306,8 @@ void DBaseStatusBar::Draw (EHudState state)
} }
else if (automapactive) else if (automapactive)
{ {
int y, time = level.time / TICRATE, height; int y, time = Tics2Seconds(level.time), height;
int totaltime = level.totaltime / TICRATE; int totaltime = Tics2Seconds(level.totaltime);
EColorRange highlight = (gameinfo.gametype & GAME_DoomChex) ? EColorRange highlight = (gameinfo.gametype & GAME_DoomChex) ?
CR_UNTRANSLATED : CR_YELLOW; CR_UNTRANSLATED : CR_YELLOW;

View file

@ -586,14 +586,17 @@ private:
screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_Alpha, FRACUNIT*3/4, TAG_DONE); screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_Alpha, FRACUNIT*3/4, TAG_DONE);
screen->DrawTexture (Images[bars], left, top, DTA_CleanNoMove, true, TAG_DONE); screen->DrawTexture (Images[bars], left, top, DTA_CleanNoMove, true, TAG_DONE);
switch (CurrentPop) switch (CurrentPop)
{ {
case POP_Log: case POP_Log:
{
int seconds = Tics2Seconds(level.time);
// Draw the latest log message. // Draw the latest log message.
mysnprintf(buff, countof(buff), "%02d:%02d:%02d", mysnprintf(buff, countof(buff), "%02d:%02d:%02d",
(level.time/TICRATE)/3600, seconds / 3600,
((level.time/TICRATE)%3600)/60, (seconds % 3600) / 60,
(level.time/TICRATE)%60); (seconds) % 60);
screen->DrawText(SmallFont2, CR_UNTRANSLATED, left + 210 * xscale, top + 8 * yscale, buff, screen->DrawText(SmallFont2, CR_UNTRANSLATED, left + 210 * xscale, top + 8 * yscale, buff,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
@ -609,6 +612,7 @@ private:
V_FreeBrokenLines(lines); V_FreeBrokenLines(lines);
} }
break; break;
}
case POP_Keys: case POP_Keys:
// List the keys the player has. // List the keys the player has.

View file

@ -120,6 +120,17 @@ FRandom pr_acs ("ACS");
#define SDF_ABSANGLE 1 #define SDF_ABSANGLE 1
#define SDF_PERMANENT 2 #define SDF_PERMANENT 2
// GetArmorInfo
enum
{
ARMORINFO_CLASSNAME,
ARMORINFO_SAVEAMOUNT,
ARMORINFO_SAVEPERCENT,
ARMORINFO_MAXABSORB,
ARMORINFO_MAXFULLABSORB,
ARMORINFO_ACTUALSAVEAMOUNT,
};
struct CallReturn struct CallReturn
{ {
CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway) CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway)
@ -4349,6 +4360,7 @@ enum EACSFunctions
ACSF_GetActorPowerupTics, ACSF_GetActorPowerupTics,
ACSF_ChangeActorAngle, ACSF_ChangeActorAngle,
ACSF_ChangeActorPitch, // 80 ACSF_ChangeActorPitch, // 80
ACSF_GetArmorInfo,
/* Zandronum's - these must be skipped when we reach 99! /* Zandronum's - these must be skipped when we reach 99!
-100:ResetMap(0), -100:ResetMap(0),
@ -4822,6 +4834,41 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const
return 0; return 0;
} }
case ACSF_GetArmorInfo:
{
if (activator == NULL || activator->player == NULL) return 0;
ABasicArmor * equippedarmor = (ABasicArmor *) activator->FindInventory(NAME_BasicArmor);
if (equippedarmor && equippedarmor->Amount != 0)
{
switch(args[0])
{
case ARMORINFO_CLASSNAME:
return GlobalACSStrings.AddString(equippedarmor->ArmorType.GetChars(), stack, stackdepth);
case ARMORINFO_SAVEAMOUNT:
return equippedarmor->MaxAmount;
case ARMORINFO_SAVEPERCENT:
return equippedarmor->SavePercent;
case ARMORINFO_MAXABSORB:
return equippedarmor->MaxAbsorb;
case ARMORINFO_MAXFULLABSORB:
return equippedarmor->MaxFullAbsorb;
case ARMORINFO_ACTUALSAVEAMOUNT:
return equippedarmor->ActualSaveAmount;
default:
return 0;
}
}
return args[0] == ARMORINFO_CLASSNAME ? GlobalACSStrings.AddString("None", stack, stackdepth) : 0;
}
case ACSF_SpawnSpotForced: case ACSF_SpawnSpotForced:
return DoSpawnSpot(args[0], args[1], args[2], args[3], true); return DoSpawnSpot(args[0], args[1], args[2], args[3], true);

View file

@ -20,8 +20,8 @@
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
//#define SHADE2LIGHT(s) (clamp (160-2*(s), 0, 255)) //#define SHADE2LIGHT(s) (160-2*(s))
#define SHADE2LIGHT(s) (clamp (255-2*s, 0, 255)) #define SHADE2LIGHT(s) (255-2*s)
// TYPES ------------------------------------------------------------------- // TYPES -------------------------------------------------------------------
@ -249,7 +249,7 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *
BYTE infoBlock[37]; BYTE infoBlock[37];
int mapver = data[5]; int mapver = data[5];
DWORD matt; DWORD matt;
int numRevisions, numWalls, numsprites, skyLen; int numRevisions, numWalls, numsprites, skyLen, visibility, parallaxType;
int i; int i;
int k; int k;
@ -269,11 +269,14 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *
{ {
memcpy (infoBlock, data + 6, 37); memcpy (infoBlock, data + 6, 37);
} }
skyLen = 2 << LittleShort(*(WORD *)(infoBlock + 16));
visibility = LittleLong(*(DWORD *)(infoBlock + 18));
parallaxType = infoBlock[26];
numRevisions = LittleLong(*(DWORD *)(infoBlock + 27)); numRevisions = LittleLong(*(DWORD *)(infoBlock + 27));
numsectors = LittleShort(*(WORD *)(infoBlock + 31)); numsectors = LittleShort(*(WORD *)(infoBlock + 31));
numWalls = LittleShort(*(WORD *)(infoBlock + 33)); numWalls = LittleShort(*(WORD *)(infoBlock + 33));
numsprites = LittleShort(*(WORD *)(infoBlock + 35)); numsprites = LittleShort(*(WORD *)(infoBlock + 35));
skyLen = 2 << LittleShort(*(WORD *)(infoBlock + 16)); Printf("Visibility: %d\n", visibility);
if (mapver == 7) if (mapver == 7)
{ {

View file

@ -3466,31 +3466,33 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
// //
//========================================================================== //==========================================================================
static ETraceStatus CheckForGhost (FTraceResults &res, void *userdata) struct Origin
{
AActor *Caller;
bool hitGhosts;
bool hitSameSpecies;
};
static ETraceStatus CheckForActor(FTraceResults &res, void *userdata)
{ {
if (res.HitType != TRACE_HitActor) if (res.HitType != TRACE_HitActor)
{ {
return TRACE_Stop; return TRACE_Stop;
} }
// check for physical attacks on a ghost Origin *data = (Origin *)userdata;
if (res.Actor->flags3 & MF3_GHOST || res.Actor->flags4 & MF4_SPECTRAL)
// check for physical attacks on spectrals
if (res.Actor->flags4 & MF4_SPECTRAL)
{ {
return TRACE_Skip; return TRACE_Skip;
} }
return TRACE_Stop; if (data->hitSameSpecies && res.Actor->GetSpecies() == data->Caller->GetSpecies())
}
static ETraceStatus CheckForSpectral (FTraceResults &res, void *userdata)
{ {
if (res.HitType != TRACE_HitActor) return TRACE_Skip;
{
return TRACE_Stop;
} }
if (data->hitGhosts && res.Actor->flags3 & MF3_GHOST)
// check for physical attacks on spectrals
if (res.Actor->flags4 & MF4_SPECTRAL)
{ {
return TRACE_Skip; return TRACE_Skip;
} }
@ -3511,9 +3513,10 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
{ {
fixed_t vx, vy, vz, shootz; fixed_t vx, vy, vz, shootz;
FTraceResults trace; FTraceResults trace;
Origin TData;
TData.Caller = t1;
angle_t srcangle = angle; angle_t srcangle = angle;
int srcpitch = pitch; int srcpitch = pitch;
bool hitGhosts;
bool killPuff = false; bool killPuff = false;
AActor *puff = NULL; AActor *puff = NULL;
int pflag = 0; int pflag = 0;
@ -3556,11 +3559,13 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
// We need to check the defaults of the replacement here // We need to check the defaults of the replacement here
AActor *puffDefaults = GetDefaultByType(pufftype->GetReplacement()); AActor *puffDefaults = GetDefaultByType(pufftype->GetReplacement());
hitGhosts = (t1->player != NULL && TData.hitGhosts = (t1->player != NULL &&
t1->player->ReadyWeapon != NULL && t1->player->ReadyWeapon != NULL &&
(t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) || (t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) ||
(puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST)); (puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST));
TData.hitSameSpecies = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES));
// if the puff uses a non-standard damage type, this will override default, hitscan and melee damage type. // if the puff uses a non-standard damage type, this will override default, hitscan and melee damage type.
// All other explicitly passed damage types (currenty only MDK) will be preserved. // All other explicitly passed damage types (currenty only MDK) will be preserved.
if ((damageType == NAME_None || damageType == NAME_Melee || damageType == NAME_Hitscan) && if ((damageType == NAME_None || damageType == NAME_Melee || damageType == NAME_Hitscan) &&
@ -3575,7 +3580,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
if (!Trace(t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance, if (!Trace(t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance,
MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace,
tflags, hitGhosts ? CheckForGhost : CheckForSpectral)) tflags, CheckForActor, &TData))
{ // hit nothing { // hit nothing
if (puffDefaults == NULL) if (puffDefaults == NULL)
{ {
@ -5274,8 +5279,7 @@ bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil, boo
break; break;
} }
} }
} } while (n);
while (n);
} }
} }
P_Recalculate3DFloors(sector); // Must recalculate the 3d floor and light lists P_Recalculate3DFloors(sector); // Must recalculate the 3d floor and light lists

View file

@ -434,8 +434,8 @@ static int R_PointOnSideSlow (fixed_t x, fixed_t y, node_t *node)
// add on a 386/486, but it certainly isn't on anything newer than that. // add on a 386/486, but it certainly isn't on anything newer than that.
fixed_t dx; fixed_t dx;
fixed_t dy; fixed_t dy;
fixed_t left; double left;
fixed_t right; double right;
if (!node->dx) if (!node->dx)
{ {
@ -466,8 +466,9 @@ static int R_PointOnSideSlow (fixed_t x, fixed_t y, node_t *node)
return 0; return 0;
} }
left = FixedMul ( node->dy>>FRACBITS , dx ); // we must use doubles here because the fixed point code will produce errors due to loss of precision for extremely short linedefs.
right = FixedMul ( dy , node->dx>>FRACBITS ); left = (double)node->dy * (double)dx;
right = (double)dy * (double)node->dx;
if (right < left) if (right < left)
{ {

View file

@ -408,7 +408,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
rw_frontcz2 <= s->floorplane.ZatPoint (curline->v2->x, curline->v2->y)) rw_frontcz2 <= s->floorplane.ZatPoint (curline->v2->x, curline->v2->y))
{ {
// Check that the window is actually visible // Check that the window is actually visible
for (int z = WallC.SX1; z < WallC.SX2; ++z) for (int z = WallC.sx1; z < WallC.sx2; ++z)
{ {
if (floorclip[z] > ceilingclip[z]) if (floorclip[z] > ceilingclip[z])
{ {
@ -541,12 +541,12 @@ 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)
{ {
if (R_CheckClipWallSegment (WallC.SX1, WallC.SX2)) if (R_CheckClipWallSegment (WallC.sx1, WallC.sx2))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
@ -695,7 +695,7 @@ void R_AddLine (seg_t *line)
// mark their subsectors as visible for automap texturing. // mark their subsectors as visible for automap texturing.
if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN)) if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN))
{ {
if (R_CheckClipWallSegment(WallC.SX1, WallC.SX2)) if (R_CheckClipWallSegment(WallC.sx1, WallC.sx2))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
@ -709,8 +709,8 @@ void R_AddLine (seg_t *line)
if (line->linedef->special == Line_Horizon) if (line->linedef->special == Line_Horizon)
{ {
// Be aware: Line_Horizon does not work properly with sloped planes // Be aware: Line_Horizon does not work properly with sloped planes
clearbufshort (walltop+WallC.SX1, WallC.SX2 - WallC.SX1, centery); clearbufshort (walltop+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
clearbufshort (wallbottom+WallC.SX1, WallC.SX2 - WallC.SX1, centery); clearbufshort (wallbottom+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
} }
else else
{ {
@ -735,7 +735,7 @@ void R_AddLine (seg_t *line)
#endif #endif
} }
if (R_ClipWallSegment (WallC.SX1, WallC.SX2, solid)) if (R_ClipWallSegment (WallC.sx1, WallC.sx2, solid))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
@ -748,58 +748,58 @@ void R_AddLine (seg_t *line)
// //
bool FWallCoords::Init(int x1, int y1, int x2, int y2, int too_close) bool FWallCoords::Init(int x1, int y1, int x2, int y2, int too_close)
{ {
TX1 = DMulScale20(x1, viewsin, -y1, viewcos); tx1 = DMulScale20(x1, viewsin, -y1, viewcos);
TX2 = DMulScale20(x2, viewsin, -y2, viewcos); tx2 = DMulScale20(x2, viewsin, -y2, viewcos);
TY1 = DMulScale20(x1, viewtancos, y1, viewtansin); ty1 = DMulScale20(x1, viewtancos, y1, viewtansin);
TY2 = DMulScale20(x2, viewtancos, y2, viewtansin); ty2 = DMulScale20(x2, viewtancos, y2, viewtansin);
if (MirrorFlags & RF_XFLIP) if (MirrorFlags & RF_XFLIP)
{ {
int t = 256 - TX1; int t = 256 - tx1;
TX1 = 256 - TX2; tx1 = 256 - tx2;
TX2 = t; tx2 = t;
swapvalues(TY1, TY2); swapvalues(ty1, ty2);
} }
if (TX1 >= -TY1) if (tx1 >= -ty1)
{ {
if (TX1 > TY1) return true; // left edge is off the right side if (tx1 > ty1) return true; // left edge is off the right side
if (TY1 == 0) return true; if (ty1 == 0) return true;
SX1 = (centerxfrac + Scale(TX1, centerxfrac, TY1)) >> FRACBITS; sx1 = (centerxfrac + Scale(tx1, centerxfrac, ty1)) >> FRACBITS;
if (TX1 >= 0) SX1 = MIN(viewwidth, SX1+1); // fix for signed divide if (tx1 >= 0) sx1 = MIN(viewwidth, sx1+1); // fix for signed divide
SZ1 = TY1; sz1 = ty1;
} }
else else
{ {
if (TX2 < -TY2) return true; // wall is off the left side if (tx2 < -ty2) return true; // wall is off the left side
fixed_t den = TX1 - TX2 - TY2 + TY1; fixed_t den = tx1 - tx2 - ty2 + ty1;
if (den == 0) return true; if (den == 0) return true;
SX1 = 0; sx1 = 0;
SZ1 = TY1 + Scale(TY2 - TY1, TX1 + TY1, den); sz1 = ty1 + Scale(ty2 - ty1, tx1 + ty1, den);
} }
if (SZ1 < too_close) if (sz1 < too_close)
return true; return true;
if (TX2 <= TY2) if (tx2 <= ty2)
{ {
if (TX2 < -TY2) return true; // right edge is off the left side if (tx2 < -ty2) return true; // right edge is off the left side
if (TY2 == 0) return true; if (ty2 == 0) return true;
SX2 = (centerxfrac + Scale(TX2, centerxfrac, TY2)) >> FRACBITS; sx2 = (centerxfrac + Scale(tx2, centerxfrac, ty2)) >> FRACBITS;
if (TX2 >= 0) SX2 = MIN(viewwidth, SX2+1); // fix for signed divide if (tx2 >= 0) sx2 = MIN(viewwidth, sx2+1); // fix for signed divide
SZ2 = TY2; sz2 = ty2;
} }
else else
{ {
if (TX1 > TY1) return true; // wall is off the right side if (tx1 > ty1) return true; // wall is off the right side
fixed_t den = TY2 - TY1 - TX2 + TX1; fixed_t den = ty2 - ty1 - tx2 + tx1;
if (den == 0) return true; if (den == 0) return true;
SX2 = viewwidth; sx2 = viewwidth;
SZ2 = TY1 + Scale(TY2 - TY1, TX1 - TY1, den); sz2 = ty1 + Scale(ty2 - ty1, tx1 - ty1, den);
} }
if (SZ2 < too_close || SX2 <= SX1) if (sz2 < too_close || sx2 <= sx1)
return true; return true;
return false; return false;
@ -809,17 +809,17 @@ void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc)
{ {
if (MirrorFlags & RF_XFLIP) if (MirrorFlags & RF_XFLIP)
{ {
UoverZorg = (float)wallc->TX2 * WallTMapScale; UoverZorg = (float)wallc->tx2 * WallTMapScale;
UoverZstep = (float)(-wallc->TY2) * 32.f; UoverZstep = (float)(-wallc->ty2) * 32.f;
InvZorg = (float)(wallc->TX2 - wallc->TX1) * WallTMapScale; InvZorg = (float)(wallc->tx2 - wallc->tx1) * WallTMapScale;
InvZstep = (float)(wallc->TY1 - wallc->TY2) * 32.f; InvZstep = (float)(wallc->ty1 - wallc->ty2) * 32.f;
} }
else else
{ {
UoverZorg = (float)wallc->TX1 * WallTMapScale; UoverZorg = (float)wallc->tx1 * WallTMapScale;
UoverZstep = (float)(-wallc->TY1) * 32.f; UoverZstep = (float)(-wallc->ty1) * 32.f;
InvZorg = (float)(wallc->TX1 - wallc->TX2) * WallTMapScale; InvZorg = (float)(wallc->tx1 - wallc->tx2) * WallTMapScale;
InvZstep = (float)(wallc->TY2 - wallc->TY1) * 32.f; InvZstep = (float)(wallc->ty2 - wallc->ty1) * 32.f;
} }
InitDepth(); InitDepth();
} }

View file

@ -33,14 +33,11 @@
struct FWallCoords struct FWallCoords
{ {
fixed_t TX1, TX2; // x coords at left, right of wall in view space fixed_t tx1, tx2; // x coords at left, right of wall in view space rx1,rx2
fixed_t TY1, TY2; // y coords at left, right of wall in view space fixed_t ty1, ty2; // y coords at left, right of wall in view space ry1,ry2
fixed_t CX1, CX2; // x coords at left, right of wall in camera space short sx1, sx2; // x coords at left, right of wall in screen space xb1,xb2
fixed_t CY1, CY2; // y coords at left, right of wall in camera space fixed_t sz1, sz2; // depth at left, right of wall in screen space yb1,yb2
int SX1, SX2; // x coords at left, right of wall in screen space
fixed_t SZ1, SZ2; // depth at left, right of wall in screen space
bool Init(int x1, int y1, int x2, int y2, int too_close); bool Init(int x1, int y1, int x2, int y2, int too_close);
}; };

View file

@ -376,10 +376,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
goto clearfog; goto clearfog;
} }
WallC.SZ1 = ds->sz1; WallC.sz1 = ds->sz1;
WallC.SZ2 = ds->sz2; WallC.sz2 = ds->sz2;
WallC.SX1 = ds->sx1; WallC.sx1 = ds->sx1;
WallC.SX2 = ds->sx2; WallC.sx2 = ds->sx2;
if (fake3D & FAKE3D_CLIPTOP) if (fake3D & FAKE3D_CLIPTOP)
{ {
@ -467,10 +467,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
} }
else else
{ // Texture does wrap vertically. { // Texture does wrap vertically.
WallC.SZ1 = ds->sz1; WallC.sz1 = ds->sz1;
WallC.SZ2 = ds->sz2; WallC.sz2 = ds->sz2;
WallC.SX1 = ds->sx1; WallC.sx1 = ds->sx1;
WallC.SX2 = ds->sx2; WallC.sx2 = ds->sx2;
if (CurrentSkybox) if (CurrentSkybox)
{ // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor
@ -587,14 +587,14 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
else if (fixedcolormap != NULL) else if (fixedcolormap != NULL)
dc_colormap = fixedcolormap; dc_colormap = fixedcolormap;
WallC.SZ1 = ds->sz1; WallC.sz1 = ds->sz1;
WallC.SZ2 = ds->sz2; WallC.sz2 = ds->sz2;
WallC.SX1 = ds->sx1; WallC.sx1 = ds->sx1;
WallC.SX2 = ds->sx2; WallC.sx2 = ds->sx2;
WallC.TX1 = ds->cx; WallC.tx1 = ds->cx;
WallC.TY1 = ds->cy; WallC.ty1 = ds->cy;
WallC.TX2 = ds->cx + ds->cdx; WallC.tx2 = ds->cx + ds->cdx;
WallC.TY2 = ds->cy + ds->cdy; WallC.ty2 = ds->cy + ds->cdy;
WallT = ds->tmapvals; WallT = ds->tmapvals;
OWallMost(wallupper, sclipTop - viewz, &WallC); OWallMost(wallupper, sclipTop - viewz, &WallC);
@ -1209,8 +1209,8 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
up = uwal; up = uwal;
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++)
@ -1821,7 +1821,7 @@ void R_RenderSegLoop ()
yscale = FixedMul(rw_pic->yScale, rw_midtexturescaley); yscale = FixedMul(rw_pic->yScale, rw_midtexturescaley);
if (xscale != lwallscale) if (xscale != lwallscale)
{ {
PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2);
lwallscale = xscale; lwallscale = xscale;
} }
if (midtexture->bWorldPanning) if (midtexture->bWorldPanning)
@ -1864,7 +1864,7 @@ void R_RenderSegLoop ()
yscale = FixedMul(rw_pic->yScale, rw_toptexturescaley); yscale = FixedMul(rw_pic->yScale, rw_toptexturescaley);
if (xscale != lwallscale) if (xscale != lwallscale)
{ {
PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2);
lwallscale = xscale; lwallscale = xscale;
} }
if (toptexture->bWorldPanning) if (toptexture->bWorldPanning)
@ -1910,7 +1910,7 @@ void R_RenderSegLoop ()
yscale = FixedMul(rw_pic->yScale, rw_bottomtexturescaley); yscale = FixedMul(rw_pic->yScale, rw_bottomtexturescaley);
if (xscale != lwallscale) if (xscale != lwallscale)
{ {
PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2);
lwallscale = xscale; lwallscale = xscale;
} }
if (bottomtexture->bWorldPanning) if (bottomtexture->bWorldPanning)
@ -2030,7 +2030,7 @@ void R_NewWall (bool needlights)
{ {
if (rw_havehigh) if (rw_havehigh)
{ // front ceiling is above back ceiling { // front ceiling is above back ceiling
memcpy (&walltop[WallC.SX1], &wallupper[WallC.SX1], (WallC.SX2 - WallC.SX1)*sizeof(walltop[0])); memcpy (&walltop[WallC.sx1], &wallupper[WallC.sx1], (WallC.sx2 - WallC.sx1)*sizeof(walltop[0]));
rw_havehigh = false; rw_havehigh = false;
} }
else if (rw_havelow && frontsector->ceilingplane != backsector->ceilingplane) else if (rw_havelow && frontsector->ceilingplane != backsector->ceilingplane)
@ -2255,15 +2255,15 @@ void R_NewWall (bool needlights)
bottomtexture ? FixedMul(bottomtexture->xScale, sidedef->GetTextureXScale(side_t::bottom)) : bottomtexture ? FixedMul(bottomtexture->xScale, sidedef->GetTextureXScale(side_t::bottom)) :
FRACUNIT; FRACUNIT;
PrepWall (swall, lwall, sidedef->TexelLength * lwallscale, WallC.SX1, WallC.SX2); PrepWall (swall, lwall, sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2);
if (fixedcolormap == NULL && fixedlightlev < 0) if (fixedcolormap == NULL && fixedlightlev < 0)
{ {
wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, frontsector->lightlevel) wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, frontsector->lightlevel)
+ r_actualextralight); + r_actualextralight);
GlobVis = r_WallVisibility; GlobVis = r_WallVisibility;
rw_lightleft = SafeDivScale12 (GlobVis, WallC.SZ1); rw_lightleft = SafeDivScale12 (GlobVis, WallC.sz1);
rw_lightstep = (SafeDivScale12 (GlobVis, WallC.SZ2) - rw_lightleft) / (WallC.SX2 - WallC.SX1); rw_lightstep = (SafeDivScale12 (GlobVis, WallC.sz2) - rw_lightleft) / (WallC.sx2 - WallC.sx1);
} }
else else
{ {
@ -2337,19 +2337,19 @@ void R_StoreWallRange (int start, int stop)
} }
rw_offset = sidedef->GetTextureXOffset(side_t::mid); rw_offset = sidedef->GetTextureXOffset(side_t::mid);
rw_light = rw_lightleft + rw_lightstep * (start - WallC.SX1); rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1);
ds_p->sx1 = WallC.SX1; ds_p->sx1 = WallC.sx1;
ds_p->sx2 = WallC.SX2; ds_p->sx2 = WallC.sx2;
ds_p->sz1 = WallC.SZ1; ds_p->sz1 = WallC.sz1;
ds_p->sz2 = WallC.SZ2; ds_p->sz2 = WallC.sz2;
ds_p->cx = WallC.TX1; ds_p->cx = WallC.tx1;
ds_p->cy = WallC.TY1; ds_p->cy = WallC.ty1;
ds_p->cdx = WallC.TX2 - WallC.TX1; ds_p->cdx = WallC.tx2 - WallC.tx1;
ds_p->cdy = WallC.TY2 - WallC.TY1; ds_p->cdy = WallC.ty2 - WallC.ty1;
ds_p->tmapvals = WallT; ds_p->tmapvals = WallT;
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-1;
ds_p->curline = curline; ds_p->curline = curline;
@ -2442,7 +2442,7 @@ void R_StoreWallRange (int start, int stop)
if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) &&
(rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) && (rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) &&
(rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) && (rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) &&
(WallC.SZ1 >= TOO_CLOSE_Z && WallC.SZ2 >= TOO_CLOSE_Z)) (WallC.sz1 >= TOO_CLOSE_Z && WallC.sz2 >= TOO_CLOSE_Z))
{ {
fixed_t *swal; fixed_t *swal;
fixed_t *lwal; fixed_t *lwal;
@ -2590,59 +2590,59 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc)
fixed_t s1, s2, s3, s4; fixed_t s1, s2, s3, s4;
z = -(z >> 4); z = -(z >> 4);
s1 = MulScale16 (globaluclip, wallc->SZ1); s2 = MulScale16 (globaluclip, wallc->SZ2); s1 = MulScale16 (globaluclip, wallc->sz1); s2 = MulScale16 (globaluclip, wallc->sz2);
s3 = MulScale16 (globaldclip, wallc->SZ1); s4 = MulScale16 (globaldclip, wallc->SZ2); s3 = MulScale16 (globaldclip, wallc->sz1); s4 = MulScale16 (globaldclip, wallc->sz2);
bad = (z<s1)+((z<s2)<<1)+((z>s3)<<2)+((z>s4)<<3); bad = (z<s1)+((z<s2)<<1)+((z>s3)<<2)+((z>s4)<<3);
#if 1 #if 1
if ((bad&3) == 3) if ((bad&3) == 3)
{ {
memset (&mostbuf[wallc->SX1], 0, (wallc->SX2 - wallc->SX1)*sizeof(mostbuf[0])); memset (&mostbuf[wallc->sx1], 0, (wallc->sx2 - wallc->sx1)*sizeof(mostbuf[0]));
return bad; return bad;
} }
if ((bad&12) == 12) if ((bad&12) == 12)
{ {
clearbufshort (&mostbuf[wallc->SX1], wallc->SX2 - wallc->SX1, viewheight); clearbufshort (&mostbuf[wallc->sx1], wallc->sx2 - wallc->sx1, viewheight);
return bad; return bad;
} }
#endif #endif
ix1 = wallc->SX1; iy1 = wallc->SZ1; ix1 = wallc->sx1; iy1 = wallc->sz1;
ix2 = wallc->SX2; iy2 = wallc->SZ2; ix2 = wallc->sx2; iy2 = wallc->sz2;
#if 1 #if 1
if (bad & 3) if (bad & 3)
{ {
int t = DivScale30 (z-s1, s2-s1); int t = DivScale30 (z-s1, s2-s1);
int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); int inty = wallc->sz1 + MulScale30 (wallc->sz2 - wallc->sz1, t);
int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2 - wallc->sx1, inty);
if ((bad & 3) == 2) if ((bad & 3) == 2)
{ {
if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; }
if (wallc->SX2 > xcross) memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); if (wallc->sx2 > xcross) memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0]));
} }
else else
{ {
if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; }
if (xcross > wallc->SX1) memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); if (xcross > wallc->sx1) memset (&mostbuf[wallc->sx1], 0, (xcross-wallc->sx1)*sizeof(mostbuf[0]));
} }
} }
if (bad & 12) if (bad & 12)
{ {
int t = DivScale30 (z-s3, s4-s3); int t = DivScale30 (z-s3, s4-s3);
int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); int inty = wallc->sz1 + MulScale30 (wallc->sz2 - wallc->sz1, t);
int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2 - wallc->sx1, inty);
if ((bad & 12) == 8) if ((bad & 12) == 8)
{ {
if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; }
if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2 - xcross, viewheight); if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2 - xcross, viewheight);
} }
else else
{ {
if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; }
if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross - wallc->SX1, viewheight); if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross - wallc->sx1, viewheight);
} }
} }
@ -2660,12 +2660,12 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc)
double max = viewheight; double max = viewheight;
double zz = z / 65536.0; double zz = z / 65536.0;
#if 0 #if 0
double z1 = zz * InvZtoScale / wallc->SZ1; double z1 = zz * InvZtoScale / wallc->sz1;
double z2 = zz * InvZtoScale / wallc->SZ2 - z1; double z2 = zz * InvZtoScale / wallc->sz2 - z1;
z2 /= (wallc->SX2 - wallc->SX1); z2 /= (wallc->sx2 - wallc->sx1);
z1 += centeryfrac / 65536.0; z1 += centeryfrac / 65536.0;
for (int x = wallc->SX1; x < wallc->SX2; ++x) for (int x = wallc->sx1; x < wallc->sx2; ++x)
{ {
mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max));
z1 += z2; z1 += z2;
@ -2673,12 +2673,12 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc)
#else #else
double top, bot, i; double top, bot, i;
i = wallc->SX1 - centerx; i = wallc->sx1 - centerx;
top = WallT.UoverZorg + WallT.UoverZstep * i; top = WallT.UoverZorg + WallT.UoverZstep * i;
bot = WallT.InvZorg + WallT.InvZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i;
double cy = centeryfrac / 65536.0; double cy = centeryfrac / 65536.0;
for (int x = wallc->SX1; x < wallc->SX2; x++) for (int x = wallc->sx1; x < wallc->sx2; x++)
{ {
double frac = top / bot; double frac = top / bot;
double scale = frac * WallT.DepthScale + WallT.DepthOrg; double scale = frac * WallT.DepthScale + WallT.DepthOrg;
@ -2711,21 +2711,21 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
{ {
x = curline->v2->x; x = curline->v2->x;
y = curline->v2->y; y = curline->v2->y;
if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2))
{ {
int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); int frac = SafeDivScale30 (wallc->ty1 + wallc->tx1, den);
x -= MulScale30 (frac, x - curline->v1->x); x -= MulScale30 (frac, x - curline->v1->x);
y -= MulScale30 (frac, y - curline->v1->y); y -= MulScale30 (frac, y - curline->v1->y);
} }
z1 = viewz - plane.ZatPoint (x, y); z1 = viewz - plane.ZatPoint (x, y);
if (wallc->SX2 > wallc->SX1 + 1) if (wallc->sx2 > wallc->sx1 + 1)
{ {
x = curline->v1->x; x = curline->v1->x;
y = curline->v1->y; y = curline->v1->y;
if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2))
{ {
int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); int frac = SafeDivScale30 (wallc->ty2 - wallc->tx2, den);
x += MulScale30 (frac, curline->v2->x - x); x += MulScale30 (frac, curline->v2->x - x);
y += MulScale30 (frac, curline->v2->y - y); y += MulScale30 (frac, curline->v2->y - y);
} }
@ -2740,21 +2740,21 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
{ {
x = curline->v1->x; x = curline->v1->x;
y = curline->v1->y; y = curline->v1->y;
if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2))
{ {
int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); int frac = SafeDivScale30 (wallc->ty1 + wallc->tx1, den);
x += MulScale30 (frac, curline->v2->x - x); x += MulScale30 (frac, curline->v2->x - x);
y += MulScale30 (frac, curline->v2->y - y); y += MulScale30 (frac, curline->v2->y - y);
} }
z1 = viewz - plane.ZatPoint (x, y); z1 = viewz - plane.ZatPoint (x, y);
if (wallc->SX2 > wallc->SX1 + 1) if (wallc->sx2 > wallc->sx1 + 1)
{ {
x = curline->v2->x; x = curline->v2->x;
y = curline->v2->y; y = curline->v2->y;
if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2))
{ {
int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); int frac = SafeDivScale30 (wallc->ty2 - wallc->tx2, den);
x -= MulScale30 (frac, x - curline->v1->x); x -= MulScale30 (frac, x - curline->v1->x);
y -= MulScale30 (frac, y - curline->v1->y); y -= MulScale30 (frac, y - curline->v1->y);
} }
@ -2766,12 +2766,12 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
} }
} }
s1 = MulScale12 (globaluclip, wallc->SZ1); s2 = MulScale12 (globaluclip, wallc->SZ2); s1 = MulScale12 (globaluclip, wallc->sz1); s2 = MulScale12 (globaluclip, wallc->sz2);
s3 = MulScale12 (globaldclip, wallc->SZ1); s4 = MulScale12 (globaldclip, wallc->SZ2); s3 = MulScale12 (globaldclip, wallc->sz1); s4 = MulScale12 (globaldclip, wallc->sz2);
bad = (z1<s1)+((z2<s2)<<1)+((z1>s3)<<2)+((z2>s4)<<3); bad = (z1<s1)+((z2<s2)<<1)+((z1>s3)<<2)+((z2>s4)<<3);
ix1 = wallc->SX1; ix2 = wallc->SX2; ix1 = wallc->sx1; ix2 = wallc->sx2;
iy1 = wallc->SZ1; iy2 = wallc->SZ2; iy1 = wallc->sz1; iy2 = wallc->sz2;
oz1 = z1; oz2 = z2; oz1 = z1; oz2 = z2;
if ((bad&3) == 3) if ((bad&3) == 3)
@ -2791,9 +2791,9 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
{ {
//inty = intz / (globaluclip>>16) //inty = intz / (globaluclip>>16)
int t = SafeDivScale30 (oz1-s1, s2-s1+oz1-oz2); int t = SafeDivScale30 (oz1-s1, s2-s1+oz1-oz2);
int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); int inty = wallc->sz1 + MulScale30 (wallc->sz2-wallc->sz1,t);
int intz = oz1 + MulScale30 (oz2-oz1,t); int intz = oz1 + MulScale30 (oz2-oz1,t);
int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1, inty); int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2-wallc->sx1, inty);
//t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4));
//inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t);
@ -2801,13 +2801,13 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
if ((bad&3) == 2) if ((bad&3) == 2)
{ {
if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; }
memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0]));
} }
else else
{ {
if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; }
memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); memset (&mostbuf[wallc->sx1], 0, (xcross-wallc->sx1)*sizeof(mostbuf[0]));
} }
} }
@ -2815,9 +2815,9 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
{ {
//inty = intz / (globaldclip>>16) //inty = intz / (globaldclip>>16)
int t = SafeDivScale30 (oz1-s3, s4-s3+oz1-oz2); int t = SafeDivScale30 (oz1-s3, s4-s3+oz1-oz2);
int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); int inty = wallc->sz1 + MulScale30 (wallc->sz2-wallc->sz1,t);
int intz = oz1 + MulScale30 (oz2-oz1,t); int intz = oz1 + MulScale30 (oz2-oz1,t);
int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1,inty); int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2-wallc->sx1,inty);
//t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4));
//inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t);
@ -2825,13 +2825,13 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
if ((bad&12) == 8) if ((bad&12) == 8)
{ {
if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; }
if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2-xcross, viewheight); if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2-xcross, viewheight);
} }
else else
{ {
if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; }
if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross-wallc->SX1, viewheight); if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross-wallc->sx1, viewheight);
} }
} }
@ -3041,8 +3041,8 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
if (WallC.Init(lx, ly, lx2, ly2, TOO_CLOSE_Z)) if (WallC.Init(lx, ly, lx2, ly2, TOO_CLOSE_Z))
goto done; goto done;
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;
@ -3145,7 +3145,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
rereadcolormap = false; rereadcolormap = false;
} }
rw_light = rw_lightleft + (x1 - WallC.SX1) * rw_lightstep; rw_light = rw_lightleft + (x1 - WallC.sx1) * rw_lightstep;
if (fixedlightlev >= 0) if (fixedlightlev >= 0)
dc_colormap = usecolormap->Maps + fixedlightlev; dc_colormap = usecolormap->Maps + fixedlightlev;
else if (fixedcolormap != NULL) else if (fixedcolormap != NULL)

View file

@ -409,16 +409,15 @@ void R_DrawWallSprite(vissprite_t *spr)
{ {
int x1, x2; int x1, x2;
fixed_t yscale; fixed_t yscale;
int shade = LIGHT2SHADE(140);
x1 = MAX<int>(spr->x1, spr->wallc.SX1); x1 = MAX<int>(spr->x1, spr->wallc.sx1);
x2 = MIN<int>(spr->x2, spr->wallc.SX2 + 1); x2 = MIN<int>(spr->x2 + 1, spr->wallc.sx2 + 1);
if (x1 >= x2) if (x1 >= x2)
return; return;
WallT.InitFromWallCoords(&spr->wallc); WallT.InitFromWallCoords(&spr->wallc);
PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2); PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2);
dc_texturemid = spr->gzt - viewz; yscale = spr->yscale;
yscale = FRACUNIT; dc_texturemid = FixedDiv(spr->gzt - viewz, yscale);
if (spr->renderflags & RF_XFLIP) if (spr->renderflags & RF_XFLIP)
{ {
int right = (spr->pic->GetWidth() << FRACBITS) - 1; int right = (spr->pic->GetWidth() << FRACBITS) - 1;
@ -440,7 +439,11 @@ void R_DrawWallSprite(vissprite_t *spr)
rereadcolormap = false; rereadcolormap = false;
} }
rw_light = rw_lightleft + (x1 - spr->wallc.SX1) * rw_lightstep; int shade = LIGHT2SHADE(spr->sector->lightlevel + r_actualextralight);
GlobVis = r_WallVisibility;
rw_lightleft = SafeDivScale12(GlobVis, spr->wallc.sz1);
rw_lightstep = (SafeDivScale12(GlobVis, spr->wallc.sz2) - rw_lightleft) / (spr->wallc.sx2 - spr->wallc.sx1);
rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep;
if (fixedlightlev >= 0) if (fixedlightlev >= 0)
dc_colormap = usecolormap->Maps + fixedlightlev; dc_colormap = usecolormap->Maps + fixedlightlev;
else if (fixedcolormap != NULL) else if (fixedcolormap != NULL)
@ -1057,7 +1060,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,
@ -1070,8 +1073,9 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f
gzb = fz + yscale * scaled_bo; gzb = fz + yscale * scaled_bo;
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-1 : wallc.SX2-1; vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2-1;
vis->yscale = yscale;
vis->idepth = (unsigned)DivScale32(1, tz) >> 1; vis->idepth = (unsigned)DivScale32(1, tz) >> 1;
vis->depth = tz; vis->depth = tz;
vis->sector = thing->Sector; vis->sector = thing->Sector;
@ -2072,19 +2076,9 @@ void R_DrawSprite (vissprite_t *spr)
r1 = MAX<int> (ds->x1, x1); r1 = MAX<int> (ds->x1, x1);
r2 = MIN<int> (ds->x2, x2); r2 = MIN<int> (ds->x2, x2);
fixed_t neardepth, fardepth;
if (ds->sz1 < ds->sz2)
{
neardepth = ds->sz1, fardepth = ds->sz2;
}
else
{
neardepth = ds->sz2, fardepth = ds->sz1;
}
if (neardepth > spr->depth || (fardepth > spr->depth &&
// Check if sprite is in front of draw seg: // Check if sprite is in front of draw seg:
DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x, if (DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x,
ds->curline->v1->x - spr->gx, ds->curline->v2->y - ds->curline->v1->y) <= 0)) ds->curline->v1->x - spr->gx, ds->curline->v2->y - ds->curline->v1->y) <= 0)
{ {
// seg is behind sprite, so draw the mid texture if it has one // seg is behind sprite, so draw the mid texture if it has one
if (ds->maskedtexturecol != -1 || ds->bFogBoundary) if (ds->maskedtexturecol != -1 || ds->bFogBoundary)

View file

@ -420,7 +420,7 @@ static void StoreLevelStats()
LevelData[i].killcount = level.killed_monsters; LevelData[i].killcount = level.killed_monsters;
LevelData[i].totalsecrets = level.total_secrets; LevelData[i].totalsecrets = level.total_secrets;
LevelData[i].secretcount = level.found_secrets; LevelData[i].secretcount = level.found_secrets;
LevelData[i].leveltime = level.maptime; LevelData[i].leveltime = AdjustTics(level.maptime);
// Check for living monsters. On some maps it can happen // Check for living monsters. On some maps it can happen
// that the counter misses some. // that the counter misses some.
@ -490,7 +490,7 @@ void STAT_ChangeLevel(const char *newl)
} }
infostring.Format("%4d/%4d, %3d/%3d, %2d", statvals[0], statvals[1], statvals[2], statvals[3], validlevels); infostring.Format("%4d/%4d, %3d/%3d, %2d", statvals[0], statvals[1], statvals[2], statvals[3], validlevels);
FSessionStatistics *es = StatisticsEntry(sl, infostring, level.totaltime); FSessionStatistics *es = StatisticsEntry(sl, infostring, AdjustTics(level.totaltime));
for(unsigned i = 0; i < LevelData.Size(); i++) for(unsigned i = 0; i < LevelData.Size(); i++)
{ {

View file

@ -76,7 +76,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the // Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got. // SVN revision ever got.
#define SAVEVER 4510 #define SAVEVER 4511
#define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)

View file

@ -1460,7 +1460,7 @@ void WI_drawDeathmatchStats ()
// Draw game time // Draw game time
y += height + CleanYfac; y += height + CleanYfac;
int seconds = plrs[me].stime / TICRATE; int seconds = Tics2Seconds(plrs[me].stime);
int hours = seconds / 3600; int hours = seconds / 3600;
int minutes = (seconds % 3600) / 60; int minutes = (seconds % 3600) / 60;
seconds = seconds % 60; seconds = seconds % 60;
@ -1817,9 +1817,9 @@ void WI_updateStats ()
cnt_kills[0] = plrs[me].skills; cnt_kills[0] = plrs[me].skills;
cnt_items[0] = plrs[me].sitems; cnt_items[0] = plrs[me].sitems;
cnt_secret[0] = plrs[me].ssecret; cnt_secret[0] = plrs[me].ssecret;
cnt_time = plrs[me].stime / TICRATE; cnt_time = Tics2Seconds(plrs[me].stime);
cnt_par = wbs->partime / TICRATE; cnt_par = wbs->partime / TICRATE;
cnt_total_time = wbs->totaltime / TICRATE; cnt_total_time = Tics2Seconds(wbs->totaltime);
} }
if (sp_state == 2) if (sp_state == 2)
@ -1882,19 +1882,21 @@ void WI_updateStats ()
cnt_total_time += 3; cnt_total_time += 3;
} }
if (!gameinfo.intermissioncounter || cnt_time >= plrs[me].stime / TICRATE) int sec = Tics2Seconds(plrs[me].stime);
cnt_time = plrs[me].stime / TICRATE; if (!gameinfo.intermissioncounter || cnt_time >= sec)
cnt_time = sec;
if (!gameinfo.intermissioncounter || cnt_total_time >= wbs->totaltime / TICRATE) int tsec = Tics2Seconds(wbs->totaltime);
cnt_total_time = wbs->totaltime / TICRATE; if (!gameinfo.intermissioncounter || cnt_total_time >= tsec)
cnt_total_time = tsec;
if (!gameinfo.intermissioncounter || cnt_par >= wbs->partime / TICRATE) if (!gameinfo.intermissioncounter || cnt_par >= wbs->partime / TICRATE)
{ {
cnt_par = wbs->partime / TICRATE; cnt_par = wbs->partime / TICRATE;
if (cnt_time >= plrs[me].stime / TICRATE) if (cnt_time >= sec)
{ {
cnt_total_time = wbs->totaltime / TICRATE; cnt_total_time = tsec;
S_Sound (CHAN_VOICE | CHAN_UI, "intermission/nextstage", 1, ATTN_NONE); S_Sound (CHAN_VOICE | CHAN_UI, "intermission/nextstage", 1, ATTN_NONE);
sp_state++; sp_state++;
} }