Merge remote-tracking branch 'zdoom/master' into openal

Conflicts:
	src/s_sound.cpp
This commit is contained in:
Chris Robinson 2014-09-09 14:45:53 -07:00
commit ff6eb6df5c
62 changed files with 2200 additions and 3294 deletions

View File

@ -70,9 +70,9 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
*c = c2; *c = c2;
*d = d2; *d = d2;
#elif __PIC__ #elif defined __PIC__ && defined __i386__
/* GCC or Clang WITH position-independent code generation */ /* GCC or Clang WITH position-independent code generation, i386 only */
__asm__ __volatile__ ( __asm__ __volatile__ (
"xchgl %%ebx, %1\n" "xchgl %%ebx, %1\n"
@ -86,7 +86,7 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else #else
/* GCC or Clang WITHOUT position-independent code generation */ /* GCC or Clang WITHOUT position-independent code generation, or x86_64 */
__asm__ __volatile__ ( __asm__ __volatile__ (
"cpuid" "cpuid"

View File

@ -938,7 +938,6 @@ add_executable( zdoom WIN32
r_drawt.cpp r_drawt.cpp
r_main.cpp r_main.cpp
r_plane.cpp r_plane.cpp
r_polymost.cpp
r_segs.cpp r_segs.cpp
r_sky.cpp r_sky.cpp
r_things.cpp r_things.cpp

View File

@ -102,6 +102,7 @@ DEFINE_SPECIAL(Scroll_Texture_Left, 100, -1, -1, 2)
DEFINE_SPECIAL(Scroll_Texture_Right, 101, -1, -1, 2) DEFINE_SPECIAL(Scroll_Texture_Right, 101, -1, -1, 2)
DEFINE_SPECIAL(Scroll_Texture_Up, 102, -1, -1, 2) DEFINE_SPECIAL(Scroll_Texture_Up, 102, -1, -1, 2)
DEFINE_SPECIAL(Scroll_Texture_Down, 103, -1, -1, 2) DEFINE_SPECIAL(Scroll_Texture_Down, 103, -1, -1, 2)
DEFINE_SPECIAL(Ceiling_CrushAndRaiseSilentDist, 104, 3, 5, 5)
DEFINE_SPECIAL(Light_ForceLightning, 109, 1, 1, 1) DEFINE_SPECIAL(Light_ForceLightning, 109, 1, 1, 1)
DEFINE_SPECIAL(Light_RaiseByValue, 110, 2, 2, 2) DEFINE_SPECIAL(Light_RaiseByValue, 110, 2, 2, 2)

View File

@ -906,6 +906,7 @@ public:
fixed_t wallbouncefactor; // The bounce factor for walls can be different. fixed_t wallbouncefactor; // The bounce factor for walls can be different.
int bouncecount; // Strife's grenades only bounce twice before exploding int bouncecount; // Strife's grenades only bounce twice before exploding
fixed_t gravity; // [GRB] Gravity factor fixed_t gravity; // [GRB] Gravity factor
fixed_t Friction;
int FastChaseStrafeCount; int FastChaseStrafeCount;
fixed_t pushfactor; fixed_t pushfactor;
int lastpush; int lastpush;

View File

@ -723,7 +723,7 @@ void AddCommandString (char *cmd, int keynum)
// Note that deferred commands lose track of which key // Note that deferred commands lose track of which key
// (if any) they were pressed from. // (if any) they were pressed from.
*brkpt = ';'; *brkpt = ';';
new DWaitingCommand (brkpt, tics+1); new DWaitingCommand (brkpt, tics);
} }
return; return;
} }

View File

@ -5,6 +5,8 @@
#include "doomtype.h" #include "doomtype.h"
#include "doomdef.h"
#include "m_fixed.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -62,4 +64,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 Scale(tics, 98, 100);
}
inline int Tics2Seconds(int tics)
{
return Scale(tics, 98, (100 * TICRATE));
}
#endif #endif

View File

@ -81,6 +81,7 @@ enum
CP_SECTORFLOOROFFSET, CP_SECTORFLOOROFFSET,
CP_SETWALLYSCALE, CP_SETWALLYSCALE,
CP_SETTHINGZ, CP_SETTHINGZ,
CP_SETTAG,
}; };
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
@ -307,6 +308,15 @@ void ParseCompatibility()
sc.MustGetFloat(); sc.MustGetFloat();
CompatParams.Push(FLOAT2FIXED(sc.Float)); CompatParams.Push(FLOAT2FIXED(sc.Float));
} }
else if (sc.Compare("setsectortag"))
{
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
CompatParams.Push(CP_SETTAG);
sc.MustGetNumber();
CompatParams.Push(sc.Number);
sc.MustGetNumber();
CompatParams.Push(sc.Number);
}
else else
{ {
sc.UnGet(); sc.UnGet();
@ -520,6 +530,15 @@ void SetCompatibilityParams()
i += 3; i += 3;
break; break;
} }
case CP_SETTAG:
{
if ((unsigned)CompatParams[i + 1] < (unsigned)numsectors)
{
sectors[CompatParams[i + 1]].tag = CompatParams[i + 2];
}
i += 3;
break;
}
} }
} }
} }

View File

@ -108,10 +108,6 @@
#include "r_renderer.h" #include "r_renderer.h"
#include "p_local.h" #include "p_local.h"
#ifdef USE_POLYMOST
#include "r_polymost.h"
#endif
EXTERN_CVAR(Bool, hud_althud) EXTERN_CVAR(Bool, hud_althud)
void DrawHUD(); void DrawHUD();
@ -186,9 +182,6 @@ CUSTOM_CVAR (Int, fraglimit, 0, CVAR_SERVERINFO)
} }
} }
#ifdef USE_POLYMOST
CVAR(Bool, testpolymost, false, 0)
#endif
CVAR (Float, timelimit, 0.f, CVAR_SERVERINFO); CVAR (Float, timelimit, 0.f, CVAR_SERVERINFO);
CVAR (Int, wipetype, 1, CVAR_ARCHIVE); CVAR (Int, wipetype, 1, CVAR_ARCHIVE);
CVAR (Int, snd_drawoutput, 0, 0); CVAR (Int, snd_drawoutput, 0, 0);
@ -282,10 +275,6 @@ void D_ProcessEvents (void)
continue; // console ate the event continue; // console ate the event
if (M_Responder (ev)) if (M_Responder (ev))
continue; // menu ate the event continue; // menu ate the event
#ifdef USE_POLYMOST
if (testpolymost)
Polymost_Responder (ev);
#endif
G_Responder (ev); G_Responder (ev);
} }
} }
@ -307,9 +296,6 @@ void D_PostEvent (const event_t *ev)
} }
events[eventhead] = *ev; events[eventhead] = *ev;
if (ev->type == EV_Mouse && !paused && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling if (ev->type == EV_Mouse && !paused && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling
#ifdef USE_POLYMOST
&& !testpolymost
#endif
) )
{ {
if (Button_Mlook.bDown || freelook) if (Button_Mlook.bDown || freelook)
@ -743,15 +729,7 @@ void D_Display ()
hw2d = false; hw2d = false;
#ifdef USE_POLYMOST
if (testpolymost)
{
drawpolymosttest();
C_DrawConsole(hw2d);
M_Drawer();
}
else
#endif
{ {
unsigned int nowtime = I_FPSTime(); unsigned int nowtime = I_FPSTime();
TexMan.UpdateAnimations(nowtime); TexMan.UpdateAnimations(nowtime);

View File

@ -1276,7 +1276,7 @@ void NetUpdate (void)
// listen for other packets // listen for other packets
GetPackets (); GetPackets ();
if (!demoplayback) if (!resendOnly)
{ {
// ideally nettics[0] should be 1 - 3 tics above lowtic // ideally nettics[0] should be 1 - 3 tics above lowtic
// if we are consistantly slower, speed up time // if we are consistantly slower, speed up time
@ -1323,7 +1323,7 @@ void NetUpdate (void)
} }
oldnettics = nettics[0]; oldnettics = nettics[0];
} }
}// !demoplayback }
} }

View File

@ -154,7 +154,7 @@ static const char * const ActorNames_init[]=
"RocketAmmo", "RocketAmmo",
"RocketBox", "RocketBox",
"Cell", "Cell",
"CellBox", "CellPack",
"Shell", "Shell",
"ShellBox", "ShellBox",
"Backpack", "Backpack",

View File

@ -107,6 +107,8 @@ enum SAW_Flags
SF_RANDOMLIGHTHIT = 4, SF_RANDOMLIGHTHIT = 4,
SF_NOUSEAMMOMISS = 8, SF_NOUSEAMMOMISS = 8,
SF_NOUSEAMMO = 16, SF_NOUSEAMMO = 16,
SF_NOPULLIN = 32,
SF_NOTURN = 64,
}; };
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
@ -187,23 +189,27 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM); S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
// turn to face target // turn to face target
angle = R_PointToAngle2 (self->x, self->y, if (!(Flags & SF_NOTURN))
linetarget->x, linetarget->y);
if (angle - self->angle > ANG180)
{ {
if (angle - self->angle < (angle_t)(-ANG90/20)) angle = R_PointToAngle2(self->x, self->y,
self->angle = angle + ANG90/21; linetarget->x, linetarget->y);
if (angle - self->angle > ANG180)
{
if (angle - self->angle < (angle_t)(-ANG90 / 20))
self->angle = angle + ANG90 / 21;
else
self->angle -= ANG90 / 20;
}
else else
self->angle -= ANG90/20; {
if (angle - self->angle > ANG90 / 20)
self->angle = angle - ANG90 / 21;
else
self->angle += ANG90 / 20;
}
} }
else if (!(Flags & SF_NOPULLIN))
{ self->flags |= MF_JUSTATTACKED;
if (angle - self->angle > ANG90/20)
self->angle = angle - ANG90/21;
else
self->angle += ANG90/20;
}
self->flags |= MF_JUSTATTACKED;
} }
// //

View File

@ -525,7 +525,7 @@ level_info_t *CheckLevelRedirect (level_info_t *info);
FString CalcMapName (int episode, int level); FString CalcMapName (int episode, int level);
void G_ParseMapInfo (const char *basemapinfo); void G_ParseMapInfo (FString basemapinfo);
void G_ClearSnapshots (void); void G_ClearSnapshots (void);
void P_RemoveDefereds (); void P_RemoveDefereds ();

View File

@ -1886,7 +1886,7 @@ static void ClearMapinfo()
// //
//========================================================================== //==========================================================================
void G_ParseMapInfo (const char *basemapinfo) void G_ParseMapInfo (FString basemapinfo)
{ {
int lump, lastlump = 0; int lump, lastlump = 0;
level_info_t gamedefaults; level_info_t gamedefaults;
@ -1895,7 +1895,7 @@ void G_ParseMapInfo (const char *basemapinfo)
atterm(ClearMapinfo); atterm(ClearMapinfo);
// Parse the default MAPINFO for the current game. This lump *MUST* come from zdoom.pk3. // Parse the default MAPINFO for the current game. This lump *MUST* come from zdoom.pk3.
if (basemapinfo != NULL) if (basemapinfo.IsNotEmpty())
{ {
FMapInfoParser parse; FMapInfoParser parse;
level_info_t defaultinfo; level_info_t defaultinfo;
@ -1903,7 +1903,7 @@ void G_ParseMapInfo (const char *basemapinfo)
if (Wads.GetLumpFile(baselump) > 0) if (Wads.GetLumpFile(baselump) > 0)
{ {
I_FatalError("File %s is overriding core lump %s.", I_FatalError("File %s is overriding core lump %s.",
Wads.GetWadFullName(Wads.GetLumpFile(baselump)), basemapinfo); Wads.GetWadFullName(Wads.GetLumpFile(baselump)), basemapinfo.GetChars());
} }
parse.ParseMapInfo(baselump, gamedefaults, defaultinfo); parse.ParseMapInfo(baselump, gamedefaults, defaultinfo);
} }

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

@ -70,6 +70,7 @@ CVAR (Bool, hud_showmonsters, true,CVAR_ARCHIVE); // Show monster stats on HUD
CVAR (Bool, hud_showitems, false,CVAR_ARCHIVE); // Show item stats on HUD CVAR (Bool, hud_showitems, false,CVAR_ARCHIVE); // Show item stats on HUD
CVAR (Bool, hud_showstats, false, CVAR_ARCHIVE); // for stamina and accuracy. CVAR (Bool, hud_showstats, false, CVAR_ARCHIVE); // for stamina and accuracy.
CVAR (Bool, hud_showscore, false, CVAR_ARCHIVE); // for user maintained score CVAR (Bool, hud_showscore, false, CVAR_ARCHIVE); // for user maintained score
CVAR (Bool, hud_showweapons, true, CVAR_ARCHIVE); // Show weapons collected
CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD
CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD
@ -866,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;
@ -972,7 +973,7 @@ void DrawHUD()
CPlayer->mo->FindInventory<AHexenArmor>(), 5, hudheight-20); CPlayer->mo->FindInventory<AHexenArmor>(), 5, hudheight-20);
i=DrawKeys(CPlayer, hudwidth-4, hudheight-10); i=DrawKeys(CPlayer, hudwidth-4, hudheight-10);
i=DrawAmmo(CPlayer, hudwidth-5, i); i=DrawAmmo(CPlayer, hudwidth-5, i);
DrawWeapons(CPlayer, hudwidth-5, i); if (hud_showweapons) DrawWeapons(CPlayer, hudwidth - 5, i);
DrawInventory(CPlayer, 144, hudheight-28); DrawInventory(CPlayer, 144, hudheight-28);
if (CPlayer->camera && CPlayer->camera->player) if (CPlayer->camera && CPlayer->camera->player)
{ {
@ -993,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;
@ -1003,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,29 +586,33 @@ 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);
if (CPlayer->LogText != NULL) if (CPlayer->LogText != NULL)
{ {
FBrokenLines *lines = V_BreakLines (SmallFont2, 272, CPlayer->LogText); FBrokenLines *lines = V_BreakLines(SmallFont2, 272, CPlayer->LogText);
for (i = 0; lines[i].Width >= 0; ++i) for (i = 0; lines[i].Width >= 0; ++i)
{ {
screen->DrawText (SmallFont2, CR_UNTRANSLATED, left+24*xscale, top+(18+i*12)*yscale, screen->DrawText(SmallFont2, CR_UNTRANSLATED, left + 24 * xscale, top + (18 + i * 12)*yscale,
lines[i].Text, DTA_CleanNoMove, true, TAG_DONE); lines[i].Text, DTA_CleanNoMove, true, TAG_DONE);
} }
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

@ -54,19 +54,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const
int p1; int p1;
int p2; int p2;
switch (ld->slopetype) if (ld->dx == 0)
{ { // ST_VERTICAL
case ST_HORIZONTAL:
p1 = m_Box[BOXTOP] > ld->v1->y;
p2 = m_Box[BOXBOTTOM] > ld->v1->y;
if (ld->dx < 0)
{
p1 ^= 1;
p2 ^= 1;
}
break;
case ST_VERTICAL:
p1 = m_Box[BOXRIGHT] < ld->v1->x; p1 = m_Box[BOXRIGHT] < ld->v1->x;
p2 = m_Box[BOXLEFT] < ld->v1->x; p2 = m_Box[BOXLEFT] < ld->v1->x;
if (ld->dy < 0) if (ld->dy < 0)
@ -74,18 +63,26 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const
p1 ^= 1; p1 ^= 1;
p2 ^= 1; p2 ^= 1;
} }
break; }
else if (ld->dy == 0)
case ST_POSITIVE: { // ST_HORIZONTAL:
p1 = m_Box[BOXTOP] > ld->v1->y;
p2 = m_Box[BOXBOTTOM] > ld->v1->y;
if (ld->dx < 0)
{
p1 ^= 1;
p2 ^= 1;
}
}
else if ((ld->dy ^ ld->dx) >= 0)
{ // ST_POSITIVE:
p1 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXTOP], ld); p1 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXTOP], ld);
p2 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXBOTTOM], ld); p2 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXBOTTOM], ld);
break; }
else
case ST_NEGATIVE: { // ST_NEGATIVE:
default: // Just to assure GCC that p1 and p2 really do get initialized
p1 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXTOP], ld); p1 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXTOP], ld);
p2 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXBOTTOM], ld); p2 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXBOTTOM], ld);
break;
} }
return (p1 == p2) ? p1 : -1; return (p1 == p2) ? p1 : -1;

View File

@ -120,12 +120,24 @@ 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, bool discard, unsigned int runaway) CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway)
: ReturnFunction(func), : ReturnFunction(func),
ReturnModule(module), ReturnModule(module),
ReturnLocals(locals), ReturnLocals(locals),
ReturnArrays(arrays),
ReturnAddress(pc), ReturnAddress(pc),
bDiscardResult(discard), bDiscardResult(discard),
EntryInstrCount(runaway) EntryInstrCount(runaway)
@ -134,6 +146,7 @@ struct CallReturn
ScriptFunction *ReturnFunction; ScriptFunction *ReturnFunction;
FBehavior *ReturnModule; FBehavior *ReturnModule;
SDWORD *ReturnLocals; SDWORD *ReturnLocals;
ACSLocalArrays *ReturnArrays;
int ReturnAddress; int ReturnAddress;
int bDiscardResult; int bDiscardResult;
unsigned int EntryInstrCount; unsigned int EntryInstrCount;
@ -1673,6 +1686,26 @@ void FBehavior::SerializeVarSet (FArchive &arc, SDWORD *vars, int max)
} }
} }
static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset)
{
unsigned count = (LittleShort(static_cast<unsigned short>(((unsigned *)chunk)[1]) - 2)) / 4;
int *sizes = (int *)((BYTE *)chunk + 10);
arrays->Count = count;
if (count > 0)
{
ACSLocalArrayInfo *info = new ACSLocalArrayInfo[count];
arrays->Info = info;
for (unsigned i = 0; i < count; ++i)
{
info[i].Size = LittleLong(sizes[i]);
info[i].Offset = offset;
offset += info[i].Size;
}
}
// Return the new local variable size, with space for the arrays
return offset;
}
FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
{ {
BYTE *object; BYTE *object;
@ -1822,12 +1855,45 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
{ {
DWORD *chunk; DWORD *chunk;
Functions = FindChunk (MAKE_ID('F','U','N','C')); // Load functions
if (Functions != NULL) BYTE *funcs;
Functions = NULL;
funcs = FindChunk (MAKE_ID('F','U','N','C'));
if (funcs != NULL)
{ {
NumFunctions = LittleLong(((DWORD *)Functions)[1]) / 8; NumFunctions = LittleLong(((DWORD *)funcs)[1]) / 8;
Functions += 8; funcs += 8;
FunctionProfileData = new ACSProfileInfo[NumFunctions]; FunctionProfileData = new ACSProfileInfo[NumFunctions];
Functions = new ScriptFunction[NumFunctions];
for (i = 0; i < NumFunctions; ++i)
{
ScriptFunctionInFile *funcf = &((ScriptFunctionInFile *)funcs)[i];
ScriptFunction *funcm = &Functions[i];
funcm->ArgCount = funcf->ArgCount;
funcm->HasReturnValue = funcf->HasReturnValue;
funcm->ImportNum = funcf->ImportNum;
funcm->LocalCount = funcf->LocalCount;
funcm->Address = funcf->Address;
}
}
// Load local arrays for functions
if (NumFunctions > 0)
{
for (chunk = (DWORD *)FindChunk(MAKE_ID('F','A','R','Y')); chunk != NULL; chunk = (DWORD *)NextChunk((BYTE *)chunk))
{
int size = LittleLong(chunk[1]);
if (size >= 6)
{
unsigned int func_num = LittleShort(((WORD *)chunk)[4]);
if (func_num < (unsigned int)NumFunctions)
{
ScriptFunction *func = &Functions[func_num];
// Unlike scripts, functions do not include their arg count in their local count.
func->LocalCount = ParseLocalArrayChunk(chunk, &func->LocalArrays, func->LocalCount + func->ArgCount) - func->ArgCount;
}
}
}
} }
// Load JUMP points // Load JUMP points
@ -2135,6 +2201,11 @@ FBehavior::~FBehavior ()
delete[] ArrayStore; delete[] ArrayStore;
ArrayStore = NULL; ArrayStore = NULL;
} }
if (Functions != NULL)
{
delete[] Functions;
Functions = NULL;
}
if (FunctionProfileData != NULL) if (FunctionProfileData != NULL)
{ {
delete[] FunctionProfileData; delete[] FunctionProfileData;
@ -2302,6 +2373,21 @@ void FBehavior::LoadScriptsDirectory ()
} }
} }
// Load script array sizes. (One chunk per script that uses arrays.)
for (scripts.b = FindChunk(MAKE_ID('S','A','R','Y')); scripts.dw != NULL; scripts.b = NextChunk(scripts.b))
{
int size = LittleLong(scripts.dw[1]);
if (size >= 6)
{
int script_num = LittleShort(scripts.w[4]);
ScriptPtr *ptr = const_cast<ScriptPtr *>(FindScript(script_num));
if (ptr != NULL)
{
ptr->VarCount = ParseLocalArrayChunk(scripts.b, &ptr->LocalArrays, ptr->VarCount);
}
}
}
// Load script names (if any) // Load script names (if any)
scripts.b = FindChunk(MAKE_ID('S','N','A','M')); scripts.b = FindChunk(MAKE_ID('S','N','A','M'));
if (scripts.dw != NULL) if (scripts.dw != NULL)
@ -3530,7 +3616,8 @@ enum
APROP_MeleeRange = 38, APROP_MeleeRange = 38,
APROP_ViewHeight = 39, APROP_ViewHeight = 39,
APROP_AttackZOffset = 40, APROP_AttackZOffset = 40,
APROP_StencilColor = 41 APROP_StencilColor = 41,
APROP_Friction = 42,
}; };
// These are needed for ACS's APROP_RenderStyle // These are needed for ACS's APROP_RenderStyle
@ -3660,16 +3747,16 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
break; break;
case APROP_Friendly: case APROP_Friendly:
if (actor->CountsAsKill()) level.total_monsters--;
if (value) if (value)
{ {
if (actor->CountsAsKill()) level.total_monsters--;
actor->flags |= MF_FRIENDLY; actor->flags |= MF_FRIENDLY;
} }
else else
{ {
actor->flags &= ~MF_FRIENDLY; actor->flags &= ~MF_FRIENDLY;
if (actor->CountsAsKill()) level.total_monsters++;
} }
if (actor->CountsAsKill()) level.total_monsters++;
break; break;
@ -3764,6 +3851,9 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
actor->SetShade(value); actor->SetShade(value);
break; break;
case APROP_Friction:
actor->Friction = value;
default: default:
// do nothing. // do nothing.
break; break;
@ -3862,6 +3952,7 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack,
case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth); case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth);
case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth);
case APROP_StencilColor:return actor->fillcolor; case APROP_StencilColor:return actor->fillcolor;
case APROP_Friction: return actor->Friction;
default: return 0; default: return 0;
} }
@ -4269,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),
@ -4742,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);
@ -5460,14 +5587,50 @@ inline int getshort (int *&pc)
return res; return res;
} }
static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int &sp, bool ranged)
{
if (ranged)
{
capacity = STACK(1);
offset = STACK(2);
if (capacity < 1 || offset < 0)
{
sp -= 4;
return false;
}
sp -= 2;
}
else
{
capacity = INT_MAX;
offset = 0;
}
a = STACK(1);
offset += STACK(2);
sp -= 2;
return true;
}
int DLevelScript::RunScript () int DLevelScript::RunScript ()
{ {
DACSThinker *controller = DACSThinker::ActiveThinker; DACSThinker *controller = DACSThinker::ActiveThinker;
SDWORD *locals = localvars; SDWORD *locals = localvars;
ACSLocalArrays noarrays;
ACSLocalArrays *localarrays = &noarrays;
ScriptFunction *activeFunction = NULL; ScriptFunction *activeFunction = NULL;
FRemapTable *translation = 0; FRemapTable *translation = 0;
int resultValue = 1; int resultValue = 1;
if (InModuleScriptNumber >= 0)
{
ScriptPtr *ptr = activeBehavior->GetScriptPtr(InModuleScriptNumber);
assert(ptr != NULL);
if (ptr != NULL)
{
localarrays = &ptr->LocalArrays;
}
}
// Hexen truncates all special arguments to bytes (only when using an old MAPINFO and old ACS format // Hexen truncates all special arguments to bytes (only when using an old MAPINFO and old ACS format
const int specialargmask = ((level.flags2 & LEVEL2_HEXENHACK) && activeBehavior->GetFormat() == ACS_Old) ? 255 : ~0; const int specialargmask = ((level.flags2 & LEVEL2_HEXENHACK) && activeBehavior->GetFormat() == ACS_Old) ? 255 : ~0;
@ -5832,9 +5995,10 @@ int DLevelScript::RunScript ()
} }
sp += i; sp += i;
::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction, ::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction,
activeBehavior, mylocals, pcd == PCD_CALLDISCARD, runaway); activeBehavior, mylocals, localarrays, pcd == PCD_CALLDISCARD, runaway);
sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int); sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int);
pc = module->Ofs2PC (func->Address); pc = module->Ofs2PC (func->Address);
localarrays = &func->LocalArrays;
activeFunction = func; activeFunction = func;
activeBehavior = module; activeBehavior = module;
fmt = module->GetFormat(); fmt = module->GetFormat();
@ -5868,6 +6032,7 @@ int DLevelScript::RunScript ()
activeBehavior = ret->ReturnModule; activeBehavior = ret->ReturnModule;
fmt = activeBehavior->GetFormat(); fmt = activeBehavior->GetFormat();
locals = ret->ReturnLocals; locals = ret->ReturnLocals;
localarrays = ret->ReturnArrays;
if (!ret->bDiscardResult) if (!ret->bDiscardResult)
{ {
Stack[sp++] = value; Stack[sp++] = value;
@ -5966,6 +6131,11 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_ASSIGNSCRIPTARRAY:
localarrays->Set(locals, NEXTBYTE, STACK(2), STACK(1));
sp -= 2;
break;
case PCD_ASSIGNMAPARRAY: case PCD_ASSIGNMAPARRAY:
activeBehavior->SetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(2), STACK(1)); activeBehavior->SetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(2), STACK(1));
sp -= 2; sp -= 2;
@ -5997,6 +6167,10 @@ int DLevelScript::RunScript ()
PushToStack (ACS_GlobalVars[NEXTBYTE]); PushToStack (ACS_GlobalVars[NEXTBYTE]);
break; break;
case PCD_PUSHSCRIPTARRAY:
STACK(1) = localarrays->Get(locals, NEXTBYTE, STACK(1));
break;
case PCD_PUSHMAPARRAY: case PCD_PUSHMAPARRAY:
STACK(1) = activeBehavior->GetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(1)); STACK(1) = activeBehavior->GetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(1));
break; break;
@ -6029,6 +6203,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_ADDSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) + STACK(1));
sp -= 2;
}
break;
case PCD_ADDMAPARRAY: case PCD_ADDMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6074,6 +6256,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_SUBSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) - STACK(1));
sp -= 2;
}
break;
case PCD_SUBMAPARRAY: case PCD_SUBMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6119,6 +6309,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_MULSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) * STACK(1));
sp -= 2;
}
break;
case PCD_MULMAPARRAY: case PCD_MULMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6192,6 +6390,19 @@ int DLevelScript::RunScript ()
} }
break; break;
case PCD_DIVSCRIPTARRAY:
if (STACK(1) == 0)
{
state = SCRIPT_DivideBy0;
}
else
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) / STACK(1));
sp -= 2;
}
break;
case PCD_DIVMAPARRAY: case PCD_DIVMAPARRAY:
if (STACK(1) == 0) if (STACK(1) == 0)
{ {
@ -6280,6 +6491,19 @@ int DLevelScript::RunScript ()
} }
break; break;
case PCD_MODSCRIPTARRAY:
if (STACK(1) == 0)
{
state = SCRIPT_ModulusBy0;
}
else
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) % STACK(1));
sp -= 2;
}
break;
case PCD_MODMAPARRAY: case PCD_MODMAPARRAY:
if (STACK(1) == 0) if (STACK(1) == 0)
{ {
@ -6341,6 +6565,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_ANDSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) & STACK(1));
sp -= 2;
}
break;
case PCD_ANDMAPARRAY: case PCD_ANDMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6386,6 +6618,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_EORSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) ^ STACK(1));
sp -= 2;
}
break;
case PCD_EORMAPARRAY: case PCD_EORMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6431,6 +6671,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_ORSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) | STACK(1));
sp -= 2;
}
break;
case PCD_ORMAPARRAY: case PCD_ORMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6477,6 +6725,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_LSSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) << STACK(1));
sp -= 2;
}
break;
case PCD_LSMAPARRAY: case PCD_LSMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6522,6 +6778,14 @@ int DLevelScript::RunScript ()
sp--; sp--;
break; break;
case PCD_RSSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(2);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) >> STACK(1));
sp -= 2;
}
break;
case PCD_RSMAPARRAY: case PCD_RSMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6564,6 +6828,14 @@ int DLevelScript::RunScript ()
++ACS_GlobalVars[NEXTBYTE]; ++ACS_GlobalVars[NEXTBYTE];
break; break;
case PCD_INCSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(1);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) + 1);
sp--;
}
break;
case PCD_INCMAPARRAY: case PCD_INCMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -6605,6 +6877,14 @@ int DLevelScript::RunScript ()
--ACS_GlobalVars[NEXTBYTE]; --ACS_GlobalVars[NEXTBYTE];
break; break;
case PCD_DECSCRIPTARRAY:
{
int a = NEXTBYTE, i = STACK(1);
localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) - 1);
sp--;
}
break;
case PCD_DECMAPARRAY: case PCD_DECMAPARRAY:
{ {
int a = *(activeBehavior->MapVars[NEXTBYTE]); int a = *(activeBehavior->MapVars[NEXTBYTE]);
@ -7031,37 +7311,35 @@ scriptwait:
} }
break; break;
// Print script character array
case PCD_PRINTSCRIPTCHARARRAY:
case PCD_PRINTSCRIPTCHRANGE:
{
int capacity, offset, a, c;
if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTSCRIPTCHRANGE))
{
while (capacity-- && (c = localarrays->Get(locals, a, offset)) != '\0')
{
work += (char)c;
offset++;
}
}
}
break;
// [JB] Print map character array // [JB] Print map character array
case PCD_PRINTMAPCHARARRAY: case PCD_PRINTMAPCHARARRAY:
case PCD_PRINTMAPCHRANGE: case PCD_PRINTMAPCHRANGE:
{ {
int capacity, offset; int capacity, offset, a, c;
if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTMAPCHRANGE))
if (pcd == PCD_PRINTMAPCHRANGE)
{ {
capacity = STACK(1); while (capacity-- && (c = activeBehavior->GetArrayVal (a, offset)) != '\0')
offset = STACK(2);
if (capacity < 1 || offset < 0)
{ {
sp -= 4; work += (char)c;
break; offset++;
} }
sp -= 2;
} }
else
{
capacity = 0x7FFFFFFF;
offset = 0;
}
int a = *(activeBehavior->MapVars[STACK(1)]);
offset += STACK(2);
int c;
while(capacity-- && (c = activeBehavior->GetArrayVal (a, offset)) != '\0') {
work += (char)c;
offset++;
}
sp-= 2;
} }
break; break;
@ -7069,32 +7347,15 @@ scriptwait:
case PCD_PRINTWORLDCHARARRAY: case PCD_PRINTWORLDCHARARRAY:
case PCD_PRINTWORLDCHRANGE: case PCD_PRINTWORLDCHRANGE:
{ {
int capacity, offset; int capacity, offset, a, c;
if (pcd == PCD_PRINTWORLDCHRANGE) if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTWORLDCHRANGE))
{ {
capacity = STACK(1); while (capacity-- && (c = ACS_WorldArrays[a][offset]) != '\0')
offset = STACK(2);
if (capacity < 1 || offset < 0)
{ {
sp -= 4; work += (char)c;
break; offset++;
} }
sp -= 2;
} }
else
{
capacity = 0x7FFFFFFF;
offset = 0;
}
int a = STACK(1);
offset += STACK(2);
int c;
while(capacity-- && (c = ACS_WorldArrays[a][offset]) != '\0') {
work += (char)c;
offset++;
}
sp-= 2;
} }
break; break;
@ -7102,32 +7363,15 @@ scriptwait:
case PCD_PRINTGLOBALCHARARRAY: case PCD_PRINTGLOBALCHARARRAY:
case PCD_PRINTGLOBALCHRANGE: case PCD_PRINTGLOBALCHRANGE:
{ {
int capacity, offset; int capacity, offset, a, c;
if (pcd == PCD_PRINTGLOBALCHRANGE) if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTGLOBALCHRANGE))
{ {
capacity = STACK(1); while (capacity-- && (c = ACS_GlobalArrays[a][offset]) != '\0')
offset = STACK(2);
if (capacity < 1 || offset < 0)
{ {
sp -= 4; work += (char)c;
break; offset++;
} }
sp -= 2;
} }
else
{
capacity = 0x7FFFFFFF;
offset = 0;
}
int a = STACK(1);
offset += STACK(2);
int c;
while(capacity-- && (c = ACS_GlobalArrays[a][offset]) != '\0') {
work += (char)c;
offset++;
}
sp-= 2;
} }
break; break;
@ -8674,6 +8918,7 @@ scriptwait:
} }
break; break;
case PCD_STRCPYTOSCRIPTCHRANGE:
case PCD_STRCPYTOMAPCHRANGE: case PCD_STRCPYTOMAPCHRANGE:
case PCD_STRCPYTOWORLDCHRANGE: case PCD_STRCPYTOWORLDCHRANGE:
case PCD_STRCPYTOGLOBALCHRANGE: case PCD_STRCPYTOGLOBALCHRANGE:
@ -8704,7 +8949,7 @@ scriptwait:
break; break;
} }
for (int i = 0;i < STACK(1); i++) for (int i = 0; i < STACK(1); i++)
{ {
if (! (*(lookup++))) if (! (*(lookup++)))
{ {
@ -8715,43 +8960,55 @@ scriptwait:
switch (pcd) switch (pcd)
{ {
case PCD_STRCPYTOMAPCHRANGE: case PCD_STRCPYTOSCRIPTCHRANGE:
{ {
int a = STACK(5); int a = STACK(5);
if (a < NUM_MAPVARS && a > 0 &&
activeBehavior->MapVars[a])
{
Stack[sp-6] = activeBehavior->CopyStringToArray(*(activeBehavior->MapVars[a]), index, capacity, lookup);
}
}
break;
case PCD_STRCPYTOWORLDCHRANGE:
{
int a = STACK(5);
while (capacity-- > 0) while (capacity-- > 0)
{
ACS_WorldArrays[a][index++] = *lookup;
if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
}
Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
}
break;
case PCD_STRCPYTOGLOBALCHRANGE:
{ {
int a = STACK(5); localarrays->Set(locals, a, index++, *lookup);
if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
while (capacity-- > 0)
{
ACS_GlobalArrays[a][index++] = *lookup;
if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
}
Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
} }
break;
Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
}
break;
case PCD_STRCPYTOMAPCHRANGE:
{
int a = STACK(5);
if (a < NUM_MAPVARS && a > 0 &&
activeBehavior->MapVars[a])
{
Stack[sp-6] = activeBehavior->CopyStringToArray(*(activeBehavior->MapVars[a]), index, capacity, lookup);
}
}
break;
case PCD_STRCPYTOWORLDCHRANGE:
{
int a = STACK(5);
while (capacity-- > 0)
{
ACS_WorldArrays[a][index++] = *lookup;
if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
}
Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
}
break;
case PCD_STRCPYTOGLOBALCHRANGE:
{
int a = STACK(5);
while (capacity-- > 0)
{
ACS_GlobalArrays[a][index++] = *lookup;
if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
}
Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
}
break;
} }
sp -= 5; sp -= 5;
} }

View File

@ -144,6 +144,51 @@ struct ProfileCollector
int Index; int Index;
}; };
struct ACSLocalArrayInfo
{
unsigned int Size;
int Offset;
};
struct ACSLocalArrays
{
unsigned int Count;
ACSLocalArrayInfo *Info;
ACSLocalArrays()
{
Count = 0;
Info = NULL;
}
~ACSLocalArrays()
{
if (Info != NULL)
{
delete[] Info;
Info = NULL;
}
}
// Bounds-checking Set and Get for local arrays
void Set(int *locals, int arraynum, int arrayentry, int value)
{
if ((unsigned int)arraynum < Count &&
(unsigned int)arrayentry < Info[arraynum].Size)
{
locals[Info[arraynum].Offset + arrayentry] = value;
}
}
int Get(int *locals, int arraynum, int arrayentry)
{
if ((unsigned int)arraynum < Count &&
(unsigned int)arrayentry < Info[arraynum].Size)
{
return locals[Info[arraynum].Offset + arrayentry];
}
return 0;
}
};
// The in-memory version // The in-memory version
struct ScriptPtr struct ScriptPtr
{ {
@ -153,6 +198,7 @@ struct ScriptPtr
BYTE ArgCount; BYTE ArgCount;
WORD VarCount; WORD VarCount;
WORD Flags; WORD Flags;
ACSLocalArrays LocalArrays;
ACSProfileInfo ProfileData; ACSProfileInfo ProfileData;
}; };
@ -189,7 +235,7 @@ struct ScriptFlagsPtr
WORD Flags; WORD Flags;
}; };
struct ScriptFunction struct ScriptFunctionInFile
{ {
BYTE ArgCount; BYTE ArgCount;
BYTE LocalCount; BYTE LocalCount;
@ -198,6 +244,16 @@ struct ScriptFunction
DWORD Address; DWORD Address;
}; };
struct ScriptFunction
{
BYTE ArgCount;
BYTE HasReturnValue;
BYTE ImportNum;
int LocalCount;
DWORD Address;
ACSLocalArrays LocalArrays;
};
// Script types // Script types
enum enum
{ {
@ -285,7 +341,7 @@ private:
BYTE *Chunks; BYTE *Chunks;
ScriptPtr *Scripts; ScriptPtr *Scripts;
int NumScripts; int NumScripts;
BYTE *Functions; ScriptFunction *Functions;
ACSProfileInfo *FunctionProfileData; ACSProfileInfo *FunctionProfileData;
int NumFunctions; int NumFunctions;
ArrayInfo *ArrayStore; ArrayInfo *ArrayStore;
@ -694,8 +750,25 @@ public:
PCD_SCRIPTWAITNAMED, PCD_SCRIPTWAITNAMED,
PCD_TRANSLATIONRANGE3, PCD_TRANSLATIONRANGE3,
PCD_GOTOSTACK, PCD_GOTOSTACK,
PCD_ASSIGNSCRIPTARRAY,
PCD_PUSHSCRIPTARRAY,
PCD_ADDSCRIPTARRAY,
PCD_SUBSCRIPTARRAY,
PCD_MULSCRIPTARRAY,
PCD_DIVSCRIPTARRAY,
/*370*/ PCD_MODSCRIPTARRAY,
PCD_INCSCRIPTARRAY,
PCD_DECSCRIPTARRAY,
PCD_ANDSCRIPTARRAY,
PCD_EORSCRIPTARRAY,
PCD_ORSCRIPTARRAY,
PCD_LSSCRIPTARRAY,
PCD_RSSCRIPTARRAY,
PCD_PRINTSCRIPTCHARARRAY,
PCD_PRINTSCRIPTCHRANGE,
/*380*/ PCD_STRCPYTOSCRIPTCHRANGE,
/*363*/ PCODE_COMMAND_COUNT /*381*/ PCODE_COMMAND_COUNT
}; };
// Some constants used by ACS scripts // Some constants used by ACS scripts

View File

@ -16,11 +16,12 @@
#include "p_setup.h" #include "p_setup.h"
#include "g_level.h" #include "g_level.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "gi.h"
// 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 -------------------------------------------------------------------
@ -248,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;
@ -268,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)
{ {
@ -361,9 +365,8 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *
// BUILD info from the map we need. (Sprites are ignored.) // BUILD info from the map we need. (Sprites are ignored.)
LoadSectors (bsec); LoadSectors (bsec);
LoadWalls (bwal, numWalls, bsec); LoadWalls (bwal, numWalls, bsec);
*mapthings = new FMapThing[numsprites + 1]; *mapthings = new FMapThing[numsprites];
CreateStartSpot ((fixed_t *)infoBlock, *mapthings); *numspr = LoadSprites (bspr, xspr, numsprites, bsec, *mapthings);
*numspr = 1 + LoadSprites (bspr, xspr, numsprites, bsec, *mapthings + 1);
delete[] bsec; delete[] bsec;
delete[] bwal; delete[] bwal;
@ -687,6 +690,8 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites,
{ {
int count = 0; int count = 0;
memset(mapthings, 0, sizeof(*mapthings)*numsprites);
for (int i = 0; i < numsprites; ++i) for (int i = 0; i < numsprites; ++i)
{ {
mapthings[count].thingid = 0; mapthings[count].thingid = 0;
@ -699,29 +704,41 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites,
mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH; mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH;
mapthings[count].special = 0; mapthings[count].special = 0;
mapthings[count].gravity = FRACUNIT; mapthings[count].gravity = FRACUNIT;
mapthings[count].RenderStyle = STYLE_Count;
mapthings[count].alpha = -1;
mapthings[count].health = -1;
if (xsprites != NULL && sprites[i].lotag == 710) if (xsprites != NULL && sprites[i].lotag == 710)
{ // Blood ambient sound { // Blood ambient sound
mapthings[count].args[0] = xsprites[i].Data3; mapthings[count].args[0] = xsprites[i].Data3;
// I am totally guessing abount the volume level. 50 seems to be a pretty // I am totally guessing about the volume level. 50 seems to be a pretty
// typical value for Blood's standard maps, so I assume it's 100-based. // typical value for Blood's standard maps, so I assume it's 100-based.
mapthings[count].args[1] = xsprites[i].Data4; mapthings[count].args[1] = xsprites[i].Data4;
mapthings[count].args[2] = xsprites[i].Data1; mapthings[count].args[2] = xsprites[i].Data1;
mapthings[count].args[3] = xsprites[i].Data2; mapthings[count].args[3] = xsprites[i].Data2;
mapthings[count].args[4] = 0;
mapthings[count].type = 14065; mapthings[count].type = 14065;
} }
else if (xsprites != NULL && sprites[i].lotag == 1)
{ // Blood player start
if (xsprites[i].Data1 < 4)
mapthings[count].type = 1 + xsprites[i].Data1;
else
mapthings[count].type = gameinfo.player5start + xsprites[i].Data1 - 4;
}
else if (xsprites != NULL && sprites[i].lotag == 2)
{ // Bloodbath start
mapthings[count].type = 11;
}
else else
{ {
if (sprites[i].cstat & (16|32|32768)) continue; if (sprites[i].cstat & 32768) continue;
if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue; if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue;
mapthings[count].type = 9988; mapthings[count].type = 9988;
mapthings[count].args[0] = sprites[i].picnum & 255; mapthings[count].args[0] = sprites[i].picnum;
mapthings[count].args[1] = sprites[i].picnum >> 8;
mapthings[count].args[2] = sprites[i].xrepeat; mapthings[count].args[2] = sprites[i].xrepeat;
mapthings[count].args[3] = sprites[i].yrepeat; mapthings[count].args[3] = sprites[i].yrepeat;
mapthings[count].args[4] = (sprites[i].cstat & 14) | ((sprites[i].cstat >> 9) & 1); mapthings[count].args[4] = sprites[i].cstat;
} }
count++; count++;
} }
@ -859,22 +876,22 @@ void ACustomSprite::BeginPlay ()
char name[9]; char name[9];
Super::BeginPlay (); Super::BeginPlay ();
mysnprintf (name, countof(name), "BTIL%04d", (args[0] + args[1]*256) & 0xffff); mysnprintf (name, countof(name), "BTIL%04d", args[0] & 0xffff);
picnum = TexMan.GetTexture (name, FTexture::TEX_Build); picnum = TexMan.GetTexture (name, FTexture::TEX_Build);
scaleX = args[2] * (FRACUNIT/64); scaleX = args[2] * (FRACUNIT/64);
scaleY = args[3] * (FRACUNIT/64); scaleY = args[3] * (FRACUNIT/64);
if (args[4] & 2) int cstat = args[4];
if (cstat & 2)
{ {
RenderStyle = STYLE_Translucent; RenderStyle = STYLE_Translucent;
if (args[4] & 1) alpha = (cstat & 512) ? TRANSLUC66 : TRANSLUC33;
alpha = TRANSLUC66;
else
alpha = TRANSLUC33;
} }
if (args[4] & 4) if (cstat & 4)
renderflags |= RF_XFLIP; renderflags |= RF_XFLIP;
if (args[4] & 8) if (cstat & 8)
renderflags |= RF_YFLIP; renderflags |= RF_YFLIP;
// set face/wall/floor flags
renderflags |= ((cstat >> 4) & 3) << 12;
} }

View File

@ -133,7 +133,6 @@ void DCeiling::Tick ()
switch (m_Type) switch (m_Type)
{ {
case ceilCrushAndRaise: case ceilCrushAndRaise:
case ceilCrushAndRaiseDist:
m_Direction = -1; m_Direction = -1;
m_Speed = m_Speed1; m_Speed = m_Speed1;
if (!SN_IsMakingLoopingSound (m_Sector)) if (!SN_IsMakingLoopingSound (m_Sector))
@ -165,7 +164,6 @@ void DCeiling::Tick ()
switch (m_Type) switch (m_Type)
{ {
case ceilCrushAndRaise: case ceilCrushAndRaise:
case ceilCrushAndRaiseDist:
case ceilCrushRaiseAndStay: case ceilCrushRaiseAndStay:
m_Speed = m_Speed2; m_Speed = m_Speed2;
m_Direction = 1; m_Direction = 1;
@ -195,7 +193,6 @@ void DCeiling::Tick ()
switch (m_Type) switch (m_Type)
{ {
case ceilCrushAndRaise: case ceilCrushAndRaise:
case ceilCrushAndRaiseDist:
case ceilLowerAndCrush: case ceilLowerAndCrush:
case ceilLowerAndCrushDist: case ceilLowerAndCrushDist:
if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT) if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT)
@ -257,7 +254,6 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line,
switch (type) switch (type)
{ {
case ceilCrushAndRaise: case ceilCrushAndRaise:
case ceilCrushAndRaiseDist:
case ceilCrushRaiseAndStay: case ceilCrushRaiseAndStay:
ceiling->m_TopHeight = sec->ceilingplane.d; ceiling->m_TopHeight = sec->ceilingplane.d;
case ceilLowerAndCrush: case ceilLowerAndCrush:
@ -267,7 +263,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line,
{ {
targheight += 8*FRACUNIT; targheight += 8*FRACUNIT;
} }
else if (type == ceilLowerAndCrushDist || type == ceilCrushAndRaiseDist) else if (type == ceilCrushAndRaise)
{ {
targheight += height; targheight += height;
} }
@ -509,7 +505,7 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
// Reactivate in-stasis ceilings...for certain types. // Reactivate in-stasis ceilings...for certain types.
// This restarts a crusher after it has been stopped // This restarts a crusher after it has been stopped
if (type == DCeiling::ceilCrushAndRaise || type == DCeiling::ceilCrushAndRaiseDist) if (type == DCeiling::ceilCrushAndRaise)
{ {
P_ActivateInStasisCeiling (tag); P_ActivateInStasisCeiling (tag);
} }

View File

@ -1014,7 +1014,7 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime)
// Building nodes in debug is much slower so let's cache them only if cachetime is 0 // Building nodes in debug is much slower so let's cache them only if cachetime is 0
buildtime = 0; buildtime = 0;
#endif #endif
if (gl_cachenodes && buildtime/1000.f >= gl_cachetime) if (level.maptype != MAPTYPE_BUILD && gl_cachenodes && buildtime/1000.f >= gl_cachetime)
{ {
DPrintf("Caching nodes\n"); DPrintf("Caching nodes\n");
CreateCachedNodes(map); CreateCachedNodes(map);

View File

@ -641,7 +641,7 @@ FUNC(LS_Ceiling_CrushAndRaiseA)
FUNC(LS_Ceiling_CrushAndRaiseDist) FUNC(LS_Ceiling_CrushAndRaiseDist)
// Ceiling_CrushAndRaiseDist (tag, dist, speed, damage, crushtype) // Ceiling_CrushAndRaiseDist (tag, dist, speed, damage, crushtype)
{ {
return EV_DoCeiling (DCeiling::ceilCrushAndRaiseDist, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 0, 0, CRUSHTYPE(arg4)); return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 0, 0, CRUSHTYPE(arg4));
} }
FUNC(LS_Ceiling_CrushAndRaiseSilentA) FUNC(LS_Ceiling_CrushAndRaiseSilentA)
@ -650,6 +650,12 @@ FUNC(LS_Ceiling_CrushAndRaiseSilentA)
return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 1, 0, CRUSHTYPE(arg4)); return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 1, 0, CRUSHTYPE(arg4));
} }
FUNC(LS_Ceiling_CrushAndRaiseSilentDist)
// Ceiling_CrushAndRaiseSilentDist (tag, dist, upspeed, damage, crushtype)
{
return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 1, 0, CRUSHTYPE(arg4));
}
FUNC(LS_Ceiling_RaiseToNearest) FUNC(LS_Ceiling_RaiseToNearest)
// Ceiling_RaiseToNearest (tag, speed) // Ceiling_RaiseToNearest (tag, speed)
{ {
@ -3261,7 +3267,7 @@ lnSpecFunc LineSpecials[256] =
/* 101 */ LS_NOP, // Scroll_Texture_Right /* 101 */ LS_NOP, // Scroll_Texture_Right
/* 102 */ LS_NOP, // Scroll_Texture_Up /* 102 */ LS_NOP, // Scroll_Texture_Up
/* 103 */ LS_NOP, // Scroll_Texture_Down /* 103 */ LS_NOP, // Scroll_Texture_Down
/* 104 */ LS_NOP, /* 104 */ LS_Ceiling_CrushAndRaiseSilentDist,
/* 105 */ LS_NOP, /* 105 */ LS_NOP,
/* 106 */ LS_NOP, /* 106 */ LS_NOP,
/* 107 */ LS_NOP, /* 107 */ LS_NOP,

File diff suppressed because it is too large Load Diff

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

@ -312,7 +312,6 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck)
if (map->Encrypted) if (map->Encrypted)
{ // If it's encrypted, then it's a Blood file, presumably a map. { // If it's encrypted, then it's a Blood file, presumably a map.
map->MapLumps[0].Reader = map->file = Wads.ReopenLumpNum(lump_name);
if (!P_IsBuildMap(map)) if (!P_IsBuildMap(map))
{ {
delete map; delete map;
@ -1889,13 +1888,6 @@ void P_AdjustLine (line_t *ld)
ld->dx = v2->x - v1->x; ld->dx = v2->x - v1->x;
ld->dy = v2->y - v1->y; ld->dy = v2->y - v1->y;
if (ld->dx == 0)
ld->slopetype = ST_VERTICAL;
else if (ld->dy == 0)
ld->slopetype = ST_HORIZONTAL;
else
ld->slopetype = ((ld->dy ^ ld->dx) >= 0) ? ST_POSITIVE : ST_NEGATIVE;
if (v1->x < v2->x) if (v1->x < v2->x)
{ {
ld->bbox[BOXLEFT] = v1->x; ld->bbox[BOXLEFT] = v1->x;

View File

@ -1990,26 +1990,12 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag)
friction = (0x1EB8*amount)/0x80 + 0xD001; friction = (0x1EB8*amount)/0x80 + 0xD001;
// killough 8/28/98: prevent odd situations // killough 8/28/98: prevent odd situations
if (friction > FRACUNIT) friction = clamp(friction, 0, FRACUNIT);
friction = FRACUNIT;
if (friction < 0)
friction = 0;
// The following check might seem odd. At the time of movement, // The following check might seem odd. At the time of movement,
// the move distance is multiplied by 'friction/0x10000', so a // the move distance is multiplied by 'friction/0x10000', so a
// higher friction value actually means 'less friction'. // higher friction value actually means 'less friction'.
movefactor = FrictionToMoveFactor(friction);
// [RH] Twiddled these values so that velocity on ice (with
// friction 0xf900) is the same as in Heretic/Hexen.
if (friction >= ORIG_FRICTION) // ice
// movefactor = ((0x10092 - friction)*(0x70))/0x158;
movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
else
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
// killough 8/28/98: prevent odd situations
if (movefactor < 32)
movefactor = 32;
for (s = -1; (s = P_FindSectorFromTag (tag,s)) >= 0; ) for (s = -1; (s = P_FindSectorFromTag (tag,s)) >= 0; )
{ {

View File

@ -172,6 +172,25 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType);
void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags); void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags);
void P_SetSectorFriction (int tag, int amount, bool alterFlag); void P_SetSectorFriction (int tag, int amount, bool alterFlag);
inline fixed_t FrictionToMoveFactor(fixed_t friction)
{
fixed_t movefactor;
// [RH] Twiddled these values so that velocity on ice (with
// friction 0xf900) is the same as in Heretic/Hexen.
if (friction >= ORIG_FRICTION) // ice
// movefactor = ((0x10092 - friction)*(0x70))/0x158;
movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
else
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
// killough 8/28/98: prevent odd situations
if (movefactor < 32)
movefactor = 32;
return movefactor;
}
void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum); void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum);
// //
@ -609,7 +628,6 @@ public:
ceilLowerInstant, ceilLowerInstant,
ceilRaiseInstant, ceilRaiseInstant,
ceilCrushAndRaise, ceilCrushAndRaise,
ceilCrushAndRaiseDist,
ceilLowerAndCrush, ceilLowerAndCrush,
ceilLowerAndCrushDist, ceilLowerAndCrushDist,
ceilCrushRaiseAndStay, ceilCrushRaiseAndStay,

View File

@ -950,18 +950,6 @@ void FPolyObj::UpdateBBox ()
// Update the line's slopetype // Update the line's slopetype
line->dx = line->v2->x - line->v1->x; line->dx = line->v2->x - line->v1->x;
line->dy = line->v2->y - line->v1->y; line->dy = line->v2->y - line->v1->y;
if (!line->dx)
{
line->slopetype = ST_VERTICAL;
}
else if (!line->dy)
{
line->slopetype = ST_HORIZONTAL;
}
else
{
line->slopetype = ((line->dy ^ line->dx) >= 0) ? ST_POSITIVE : ST_NEGATIVE;
}
} }
CalcCenter(); CalcCenter();
} }

View File

@ -51,13 +51,12 @@
#include "doomstat.h" #include "doomstat.h"
#include "r_state.h" #include "r_state.h"
#include "r_bsp.h" #include "r_bsp.h"
#include "r_segs.h"
#include "v_palette.h" #include "v_palette.h"
#include "r_sky.h" #include "r_sky.h"
#include "po_man.h" #include "po_man.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
int WallMost (short *mostbuf, const secplane_t &plane);
seg_t* curline; seg_t* curline;
side_t* sidedef; side_t* sidedef;
line_t* linedef; line_t* linedef;
@ -92,18 +91,8 @@ drawseg_t* ds_p;
size_t FirstInterestingDrawseg; size_t FirstInterestingDrawseg;
TArray<size_t> InterestingDrawsegs; TArray<size_t> InterestingDrawsegs;
fixed_t WallTX1, WallTX2; // x coords at left, right of wall in view space FWallCoords WallC;
fixed_t WallTY1, WallTY2; // y coords at left, right of wall in view space FWallTmapVals WallT;
fixed_t WallCX1, WallCX2; // x coords at left, right of wall in camera space
fixed_t WallCY1, WallCY2; // y coords at left, right of wall in camera space
int WallSX1, WallSX2; // x coords at left, right of wall in screen space
fixed_t WallSZ1, WallSZ2; // depth at left, right of wall in screen space
float WallDepthOrg, WallDepthScale;
float WallUoverZorg, WallUoverZstep;
float WallInvZorg, WallInvZstep;
static BYTE FakeSide; static BYTE FakeSide;
@ -419,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 = WallSX1; z < WallSX2; ++z) for (int z = WallC.sx1; z < WallC.sx2; ++z)
{ {
if (floorclip[z] > ceilingclip[z]) if (floorclip[z] > ceilingclip[z])
{ {
@ -549,66 +538,15 @@ void R_AddLine (seg_t *line)
if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0)
return; return;
WallTX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); if (WallC.Init(tx1, ty1, tx2, ty2, 32))
WallTX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos);
WallTY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin);
WallTY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin);
if (MirrorFlags & RF_XFLIP)
{
int t = 256-WallTX1;
WallTX1 = 256-WallTX2;
WallTX2 = t;
swapvalues (WallTY1, WallTY2);
}
if (WallTX1 >= -WallTY1)
{
if (WallTX1 > WallTY1) return; // left edge is off the right side
if (WallTY1 == 0) return;
WallSX1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS;
if (WallTX1 >= 0) WallSX1 = MIN (viewwidth, WallSX1+1); // fix for signed divide
WallSZ1 = WallTY1;
}
else
{
if (WallTX2 < -WallTY2) return; // wall is off the left side
fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1;
if (den == 0) return;
WallSX1 = 0;
WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den);
}
if (WallSZ1 < 32)
return; return;
if (WallTX2 <= WallTY2) if (WallC.sx1 > WindowRight || WallC.sx2 < WindowLeft)
{
if (WallTX2 < -WallTY2) return; // right edge is off the left side
if (WallTY2 == 0) return;
WallSX2 = (centerxfrac + Scale (WallTX2, centerxfrac, WallTY2)) >> FRACBITS;
if (WallTX2 >= 0) WallSX2 = MIN (viewwidth, WallSX2+1); // fix for signed divide
WallSZ2 = WallTY2;
}
else
{
if (WallTX1 > WallTY1) return; // wall is off the right side
fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1;
if (den == 0) return;
WallSX2 = viewwidth;
WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den);
}
if (WallSZ2 < 32 || WallSX2 <= WallSX1)
return;
if (WallSX1 > WindowRight || WallSX2 < WindowLeft)
return; return;
if (line->linedef == NULL) if (line->linedef == NULL)
{ {
if (R_CheckClipWallSegment (WallSX1, WallSX2)) if (R_CheckClipWallSegment (WallC.sx1, WallC.sx2))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
@ -622,20 +560,7 @@ void R_AddLine (seg_t *line)
if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2))
{ // The seg is the entire wall. { // The seg is the entire wall.
if (MirrorFlags & RF_XFLIP) WallT.InitFromWallCoords(&WallC);
{
WallUoverZorg = (float)WallTX2 * WallTMapScale;
WallUoverZstep = (float)(-WallTY2) * 32.f;
WallInvZorg = (float)(WallTX2 - WallTX1) * WallTMapScale;
WallInvZstep = (float)(WallTY1 - WallTY2) * 32.f;
}
else
{
WallUoverZorg = (float)WallTX1 * WallTMapScale;
WallUoverZstep = (float)(-WallTY1) * 32.f;
WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale;
WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f;
}
} }
else else
{ // The seg is only part of the wall. { // The seg is only part of the wall.
@ -643,29 +568,8 @@ void R_AddLine (seg_t *line)
{ {
swapvalues (v1, v2); swapvalues (v1, v2);
} }
tx1 = v1->x - viewx; WallT.InitFromLine(v1->x - viewx, v1->y - viewy, v2->x - viewx, v2->y - viewy);
tx2 = v2->x - viewx;
ty1 = v1->y - viewy;
ty2 = v2->y - viewy;
fixed_t fullx1 = DMulScale20 (tx1, viewsin, -ty1, viewcos);
fixed_t fullx2 = DMulScale20 (tx2, viewsin, -ty2, viewcos);
fixed_t fully1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin);
fixed_t fully2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin);
if (MirrorFlags & RF_XFLIP)
{
fullx1 = -fullx1;
fullx2 = -fullx2;
}
WallUoverZorg = (float)fullx1 * WallTMapScale;
WallUoverZstep = (float)(-fully1) * 32.f;
WallInvZorg = (float)(fullx1 - fullx2) * WallTMapScale;
WallInvZstep = (float)(fully2 - fully1) * 32.f;
} }
WallDepthScale = WallInvZstep * WallTMapScale2;
WallDepthOrg = -WallUoverZstep * WallTMapScale2;
if (!(fake3D & FAKE3D_FAKEBACK)) if (!(fake3D & FAKE3D_FAKEBACK))
{ {
@ -703,12 +607,12 @@ void R_AddLine (seg_t *line)
if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2) if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2)
{ {
rw_havehigh = true; rw_havehigh = true;
WallMost (wallupper, backsector->ceilingplane); WallMost (wallupper, backsector->ceilingplane, &WallC);
} }
if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2) if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2)
{ {
rw_havelow = true; rw_havelow = true;
WallMost (walllower, backsector->floorplane); WallMost (walllower, backsector->floorplane, &WallC);
} }
// Closed door. // Closed door.
@ -791,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(WallSX1, WallSX2)) if (R_CheckClipWallSegment(WallC.sx1, WallC.sx2))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
@ -805,13 +709,13 @@ 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+WallSX1, WallSX2 - WallSX1, centery); clearbufshort (walltop+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
clearbufshort (wallbottom+WallSX1, WallSX2 - WallSX1, centery); clearbufshort (wallbottom+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
} }
else else
{ {
rw_ceilstat = WallMost (walltop, frontsector->ceilingplane); rw_ceilstat = WallMost (walltop, frontsector->ceilingplane, &WallC);
rw_floorstat = WallMost (wallbottom, frontsector->floorplane); rw_floorstat = WallMost (wallbottom, frontsector->floorplane, &WallC);
// [RH] treat off-screen walls as solid // [RH] treat off-screen walls as solid
#if 0 // Maybe later... #if 0 // Maybe later...
@ -831,12 +735,120 @@ void R_AddLine (seg_t *line)
#endif #endif
} }
if (R_ClipWallSegment (WallSX1, WallSX2, solid)) if (R_ClipWallSegment (WallC.sx1, WallC.sx2, solid))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
} }
//
// FWallCoords :: Init
//
// Transform and clip coordinates. Returns true if it was clipped away
//
bool FWallCoords::Init(int x1, int y1, int x2, int y2, int too_close)
{
tx1 = DMulScale20(x1, viewsin, -y1, viewcos);
tx2 = DMulScale20(x2, viewsin, -y2, viewcos);
ty1 = DMulScale20(x1, viewtancos, y1, viewtansin);
ty2 = DMulScale20(x2, viewtancos, y2, viewtansin);
if (MirrorFlags & RF_XFLIP)
{
int t = 256 - tx1;
tx1 = 256 - tx2;
tx2 = t;
swapvalues(ty1, ty2);
}
if (tx1 >= -ty1)
{
if (tx1 > ty1) return true; // left edge is off the right side
if (ty1 == 0) return true;
sx1 = (centerxfrac + Scale(tx1, centerxfrac, ty1)) >> FRACBITS;
if (tx1 >= 0) sx1 = MIN(viewwidth, sx1+1); // fix for signed divide
sz1 = ty1;
}
else
{
if (tx2 < -ty2) return true; // wall is off the left side
fixed_t den = tx1 - tx2 - ty2 + ty1;
if (den == 0) return true;
sx1 = 0;
sz1 = ty1 + Scale(ty2 - ty1, tx1 + ty1, den);
}
if (sz1 < too_close)
return true;
if (tx2 <= ty2)
{
if (tx2 < -ty2) return true; // right edge is off the left side
if (ty2 == 0) return true;
sx2 = (centerxfrac + Scale(tx2, centerxfrac, ty2)) >> FRACBITS;
if (tx2 >= 0) sx2 = MIN(viewwidth, sx2+1); // fix for signed divide
sz2 = ty2;
}
else
{
if (tx1 > ty1) return true; // wall is off the right side
fixed_t den = ty2 - ty1 - tx2 + tx1;
if (den == 0) return true;
sx2 = viewwidth;
sz2 = ty1 + Scale(ty2 - ty1, tx1 - ty1, den);
}
if (sz2 < too_close || sx2 <= sx1)
return true;
return false;
}
void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc)
{
if (MirrorFlags & RF_XFLIP)
{
UoverZorg = (float)wallc->tx2 * WallTMapScale;
UoverZstep = (float)(-wallc->ty2) * 32.f;
InvZorg = (float)(wallc->tx2 - wallc->tx1) * WallTMapScale;
InvZstep = (float)(wallc->ty1 - wallc->ty2) * 32.f;
}
else
{
UoverZorg = (float)wallc->tx1 * WallTMapScale;
UoverZstep = (float)(-wallc->ty1) * 32.f;
InvZorg = (float)(wallc->tx1 - wallc->tx2) * WallTMapScale;
InvZstep = (float)(wallc->ty2 - wallc->ty1) * 32.f;
}
InitDepth();
}
void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2)
{ // Coordinates should have already had viewx,viewy subtracted
fixed_t fullx1 = DMulScale20 (tx1, viewsin, -ty1, viewcos);
fixed_t fullx2 = DMulScale20 (tx2, viewsin, -ty2, viewcos);
fixed_t fully1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin);
fixed_t fully2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin);
if (MirrorFlags & RF_XFLIP)
{
fullx1 = -fullx1;
fullx2 = -fullx2;
}
UoverZorg = (float)fullx1 * WallTMapScale;
UoverZstep = (float)(-fully1) * 32.f;
InvZorg = (float)(fullx1 - fullx2) * WallTMapScale;
InvZstep = (float)(fully2 - fully1) * 32.f;
InitDepth();
}
void FWallTmapVals::InitDepth()
{
DepthScale = InvZstep * WallTMapScale2;
DepthOrg = -UoverZstep * WallTMapScale2;
}
// //
// R_CheckBBox // R_CheckBBox

View File

@ -26,6 +26,36 @@
#include "tarray.h" #include "tarray.h"
#include <stddef.h> #include <stddef.h>
// The 3072 below is just an arbitrary value picked to avoid
// drawing lines the player is too close to that would overflow
// the texture calculations.
#define TOO_CLOSE_Z 3072
struct FWallCoords
{
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 ry1,ry2
short sx1, sx2; // x coords at left, right of wall in screen space xb1,xb2
fixed_t sz1, sz2; // depth at left, right of wall in screen space yb1,yb2
bool Init(int x1, int y1, int x2, int y2, int too_close);
};
struct FWallTmapVals
{
float DepthOrg, DepthScale;
float UoverZorg, UoverZstep;
float InvZorg, InvZstep;
void InitFromWallCoords(const FWallCoords *wallc);
void InitFromLine(int x1, int y1, int x2, int y2);
void InitDepth();
};
extern FWallCoords WallC;
extern FWallTmapVals WallT;
enum enum
{ {
FAKED_Center, FAKED_Center,
@ -33,7 +63,6 @@ enum
FAKED_AboveCeiling FAKED_AboveCeiling
}; };
struct drawseg_t struct drawseg_t
{ {
seg_t* curline; seg_t* curline;
@ -58,7 +87,7 @@ struct drawseg_t
int fake; // ident fake drawseg, don't draw and clip sprites int fake; // ident fake drawseg, don't draw and clip sprites
// backups // backups
ptrdiff_t bkup; // sprtopclip backup, for mid and fake textures ptrdiff_t bkup; // sprtopclip backup, for mid and fake textures
float WallUoverZorg, WallUoverZstep, WallInvZorg, WallInvZstep, WallDepthScale, WallDepthOrg; FWallTmapVals tmapvals;
}; };

View File

@ -925,8 +925,6 @@ void R_InitSprites ()
numskins++; numskins++;
} }
SpriteFrames.Clear();
// [RH] Do some preliminary setup // [RH] Do some preliminary setup
if (skins != NULL) delete [] skins; if (skins != NULL) delete [] skins;
skins = new FPlayerSkin[numskins]; skins = new FPlayerSkin[numskins];

View File

@ -882,18 +882,6 @@ struct side_t
FArchive &operator<< (FArchive &arc, side_t::part &p); FArchive &operator<< (FArchive &arc, side_t::part &p);
//
// Move clipping aid for LineDefs.
//
enum slopetype_t
{
ST_HORIZONTAL,
ST_VERTICAL,
ST_POSITIVE,
ST_NEGATIVE
};
struct line_t struct line_t
{ {
vertex_t *v1, *v2; // vertices, from v1 to v2 vertex_t *v1, *v2; // vertices, from v1 to v2
@ -908,7 +896,6 @@ struct line_t
side_t *sidedef[2]; side_t *sidedef[2];
//DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided //DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided
fixed_t bbox[4]; // bounding box, for the extent of the LineDef. fixed_t bbox[4]; // bounding box, for the extent of the LineDef.
slopetype_t slopetype; // To aid move clipping.
sector_t *frontsector, *backsector; sector_t *frontsector, *backsector;
int validcount; // if == validcount, already checked int validcount; // if == validcount, already checked
int locknumber; // [Dusk] lock number for special int locknumber; // [Dusk] lock number for special

View File

@ -72,8 +72,6 @@
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void R_SpanInitData (); void R_SpanInitData ();
void RP_RenderBSPNode (void *node);
bool RP_SetupFrame (bool backside);
void R_DeinitSprites(); void R_DeinitSprites();
// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -94,14 +92,12 @@ extern "C" int fuzzviewheight;
static float CurrentVisibility = 8.f; static float CurrentVisibility = 8.f;
static fixed_t MaxVisForWall; static fixed_t MaxVisForWall;
static fixed_t MaxVisForFloor; static fixed_t MaxVisForFloor;
static bool polyclipped;
extern bool r_showviewer; extern bool r_showviewer;
bool r_dontmaplines; bool r_dontmaplines;
// PUBLIC DATA DEFINITIONS ------------------------------------------------- // PUBLIC DATA DEFINITIONS -------------------------------------------------
CVAR (String, r_viewsize, "", CVAR_NOSET) CVAR (String, r_viewsize, "", CVAR_NOSET)
CVAR (Int, r_polymost, 0, 0)
CVAR (Bool, r_shadercolormaps, true, CVAR_ARCHIVE) CVAR (Bool, r_shadercolormaps, true, CVAR_ARCHIVE)
fixed_t r_BaseVisibility; fixed_t r_BaseVisibility;
@ -612,14 +608,6 @@ void R_SetupFreelook()
} }
} }
void R_SetupPolymost()
{
if (r_polymost)
{
polyclipped = RP_SetupFrame (false);
}
}
//========================================================================== //==========================================================================
// //
// R_EnterMirror // R_EnterMirror
@ -812,11 +800,8 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
} }
// Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function // Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function
PO_LinkToSubsectors(); PO_LinkToSubsectors();
if (r_polymost < 2) R_RenderBSPNode (nodes + numnodes - 1); // The head node is the last node output.
{ R_3D_ResetClip(); // reset clips (floor/ceiling)
R_RenderBSPNode (nodes + numnodes - 1); // The head node is the last node output.
R_3D_ResetClip(); // reset clips (floor/ceiling)
}
camera->renderflags = savedflags; camera->renderflags = savedflags;
WallCycles.Unclock(); WallCycles.Unclock();
@ -843,16 +828,6 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
MaskedCycles.Unclock(); MaskedCycles.Unclock();
NetUpdate (); NetUpdate ();
if (r_polymost)
{
RP_RenderBSPNode (nodes + numnodes - 1);
if (polyclipped)
{
RP_SetupFrame (true);
RP_RenderBSPNode (nodes + numnodes - 1);
}
}
} }
WallMirrors.Clear (); WallMirrors.Clear ();
interpolator.RestoreInterpolations (); interpolator.RestoreInterpolations ();

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
/**************************************************************************************************
"POLYMOST" code written by Ken Silverman
**************************************************************************************************/
#include "c_cvars.h"
typedef void (*pmostcallbacktype)(double *dpx, double *dpy, int n, void *userdata);
class PolyClipper
{
public:
PolyClipper();
~PolyClipper();
void InitMosts (double *px, double *py, int n);
bool TestVisibleMost (float x0, float x1);
int DoMost (float x0, float y0, float x1, float y1, pmostcallbacktype callback, void *callbackdata);
private:
struct vsptype
{
float X, Cy[2], Fy[2];
int Tag, CTag, FTag;
vsptype *Next, *Prev;
};
enum { GROUP_SIZE = 128 };
struct vspgroup
{
vspgroup (vsptype *sentinel);
vspgroup *NextGroup;
vsptype vsp[GROUP_SIZE];
};
vsptype EmptyList;
vsptype UsedList;
vspgroup vsps;
vsptype Solid;
int GTag;
vsptype *vsinsaft (vsptype *vsp);
void EmptyAll ();
void AddGroup ();
vsptype *GetVsp ();
void FreeVsp (vsptype *vsp);
friend void drawpolymosttest();
};
extern void drawpolymosttest();
struct event_t; void Polymost_Responder (event_t *ev);

View File

@ -64,11 +64,6 @@ CVAR(Bool, r_np2, true, 0)
#define HEIGHTBITS 12 #define HEIGHTBITS 12
#define HEIGHTSHIFT (FRACBITS-HEIGHTBITS) #define HEIGHTSHIFT (FRACBITS-HEIGHTBITS)
// The 3072 below is just an arbitrary value picked to avoid
// drawing lines the player is too close to that would overflow
// the texture calculations.
#define TOO_CLOSE_Z 3072
extern fixed_t globaluclip, globaldclip; extern fixed_t globaluclip, globaldclip;
@ -86,13 +81,6 @@ fixed_t rw_offset_top;
fixed_t rw_offset_mid; fixed_t rw_offset_mid;
fixed_t rw_offset_bottom; fixed_t rw_offset_bottom;
int OWallMost (short *mostbuf, fixed_t z);
int WallMost (short *mostbuf, const secplane_t &plane);
void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat);
void PrepLWall (fixed_t *lwall, fixed_t walxrepeat);
extern fixed_t WallSZ1, WallSZ2, WallTX1, WallTX2, WallTY1, WallTY2, WallCX1, WallCX2, WallCY1, WallCY2;
extern int WallSX1, WallSX2;
extern float WallUoverZorg, WallUoverZstep, WallInvZorg, WallInvZstep, WallDepthScale, WallDepthOrg;
int wallshade; int wallshade;
@ -142,7 +130,6 @@ static fixed_t rw_bottomtexturescaley;
FTexture *rw_pic; FTexture *rw_pic;
static fixed_t *maskedtexturecol; static fixed_t *maskedtexturecol;
static FTexture *WallSpriteTile;
static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass); static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass);
static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)); static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans));
@ -218,13 +205,13 @@ void ClipMidtex(int x1, int x2)
{ {
short most[MAXWIDTH]; short most[MAXWIDTH];
WallMost(most, curline->frontsector->ceilingplane); 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); 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])
@ -389,26 +376,26 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
goto clearfog; goto clearfog;
} }
WallSZ1 = ds->sz1; WallC.sz1 = ds->sz1;
WallSZ2 = ds->sz2; WallC.sz2 = ds->sz2;
WallSX1 = ds->sx1; WallC.sx1 = ds->sx1;
WallSX2 = ds->sx2; WallC.sx2 = ds->sx2;
if (fake3D & FAKE3D_CLIPTOP) if (fake3D & FAKE3D_CLIPTOP)
{ {
OWallMost (wallupper, textop < sclipTop - viewz ? textop : sclipTop - viewz); OWallMost(wallupper, textop < sclipTop - viewz ? textop : sclipTop - viewz, &WallC);
} }
else else
{ {
OWallMost (wallupper, textop); OWallMost(wallupper, textop, &WallC);
} }
if (fake3D & FAKE3D_CLIPBOTTOM) if (fake3D & FAKE3D_CLIPBOTTOM)
{ {
OWallMost (walllower, textop - texheight > sclipBottom - viewz ? textop - texheight : sclipBottom - viewz); OWallMost(walllower, textop - texheight > sclipBottom - viewz ? textop - texheight : sclipBottom - viewz, &WallC);
} }
else else
{ {
OWallMost (walllower, textop - texheight); OWallMost(walllower, textop - texheight, &WallC);
} }
for (i = x1; i <= x2; i++) for (i = x1; i <= x2; i++)
@ -480,10 +467,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
} }
else else
{ // Texture does wrap vertically. { // Texture does wrap vertically.
WallSZ1 = ds->sz1; WallC.sz1 = ds->sz1;
WallSZ2 = ds->sz2; WallC.sz2 = ds->sz2;
WallSX1 = ds->sx1; WallC.sx1 = ds->sx1;
WallSX2 = 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
@ -498,7 +485,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
if (fake3D & FAKE3D_CLIPTOP) if (fake3D & FAKE3D_CLIPTOP)
{ {
OWallMost (wallupper, sclipTop - viewz); 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])
@ -508,7 +495,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
} }
if (fake3D & FAKE3D_CLIPBOTTOM) if (fake3D & FAKE3D_CLIPBOTTOM)
{ {
OWallMost (walllower, sclipBottom - viewz); 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])
@ -600,23 +587,18 @@ 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;
WallSZ1 = ds->sz1; WallC.sz1 = ds->sz1;
WallSZ2 = ds->sz2; WallC.sz2 = ds->sz2;
WallSX1 = ds->sx1; WallC.sx1 = ds->sx1;
WallSX2 = ds->sx2; WallC.sx2 = ds->sx2;
WallTX1 = ds->cx; WallC.tx1 = ds->cx;
WallTY1 = ds->cy; WallC.ty1 = ds->cy;
WallTX2 = WallTX1 + ds->cdx; WallC.tx2 = ds->cx + ds->cdx;
WallTY2 = WallTY1 + ds->cdy; WallC.ty2 = ds->cy + ds->cdy;
WallDepthScale = ds->WallDepthScale; WallT = ds->tmapvals;
WallDepthOrg = ds->WallDepthOrg;
WallUoverZorg = ds->WallUoverZorg;
WallUoverZstep = ds->WallUoverZstep;
WallInvZorg = ds->WallInvZorg;
WallInvZstep = ds->WallInvZstep;
OWallMost(wallupper, sclipTop - viewz); OWallMost(wallupper, sclipTop - viewz, &WallC);
OWallMost(walllower, sclipBottom - viewz); OWallMost(walllower, sclipBottom - viewz, &WallC);
for (i = x1; i <= x2; i++) for (i = x1; i <= x2; i++)
{ {
@ -629,7 +611,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
walllower[i] = mfloorclip[i]; walllower[i] = mfloorclip[i];
} }
PrepLWall (lwall, curline->sidedef->TexelLength*xscale); PrepLWall (lwall, curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2);
wallscan_np2_ds(ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale); wallscan_np2_ds(ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale);
R_FinishSetPatchStyle(); R_FinishSetPatchStyle();
} }
@ -1227,13 +1209,13 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
up = uwal; up = uwal;
down = most1; down = most1;
assert(WallSX1 <= x1); assert(WallC.sx1 <= x1);
assert(WallSX2 > 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++)
{ {
int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane); 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)
@ -1315,7 +1297,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed
dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight; dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight;
while (partition > bot) while (partition > bot)
{ {
int j = OWallMost(most3, partition - viewz); 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)
@ -1339,7 +1321,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed
dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight; dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight;
while (partition < top) while (partition < top)
{ {
int j = OWallMost(most3, partition - viewz); 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)
@ -1839,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); PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2);
lwallscale = xscale; lwallscale = xscale;
} }
if (midtexture->bWorldPanning) if (midtexture->bWorldPanning)
@ -1882,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); PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2);
lwallscale = xscale; lwallscale = xscale;
} }
if (toptexture->bWorldPanning) if (toptexture->bWorldPanning)
@ -1928,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); PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2);
lwallscale = xscale; lwallscale = xscale;
} }
if (bottomtexture->bWorldPanning) if (bottomtexture->bWorldPanning)
@ -2048,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[WallSX1], &wallupper[WallSX1], (WallSX2 - WallSX1)*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)
@ -2058,7 +2040,7 @@ void R_NewWall (bool needlights)
// wall but nothing to draw for it. // wall but nothing to draw for it.
// Recalculate walltop so that the wall is clipped by the back sector's // Recalculate walltop so that the wall is clipped by the back sector's
// ceiling instead of the front sector's ceiling. // ceiling instead of the front sector's ceiling.
WallMost (walltop, backsector->ceilingplane); WallMost (walltop, backsector->ceilingplane, &WallC);
} }
// Putting sky ceilings on the front and back of a line alters the way unpegged // Putting sky ceilings on the front and back of a line alters the way unpegged
// positioning works. // positioning works.
@ -2273,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); 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, WallSZ1); rw_lightleft = SafeDivScale12 (GlobVis, WallC.sz1);
rw_lightstep = (SafeDivScale12 (GlobVis, WallSZ2) - rw_lightleft) / (WallSX2 - WallSX1); rw_lightstep = (SafeDivScale12 (GlobVis, WallC.sz2) - rw_lightleft) / (WallC.sx2 - WallC.sx1);
} }
else else
{ {
@ -2355,24 +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 - WallSX1); rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1);
ds_p->sx1 = WallSX1; ds_p->sx1 = WallC.sx1;
ds_p->sx2 = WallSX2; ds_p->sx2 = WallC.sx2;
ds_p->sz1 = WallSZ1; ds_p->sz1 = WallC.sz1;
ds_p->sz2 = WallSZ2; ds_p->sz2 = WallC.sz2;
ds_p->cx = WallTX1; ds_p->cx = WallC.tx1;
ds_p->cy = WallTY1; ds_p->cy = WallC.ty1;
ds_p->cdx = WallTX2 - WallTX1; ds_p->cdx = WallC.tx2 - WallC.tx1;
ds_p->cdy = WallTY2 - WallTY1; ds_p->cdy = WallC.ty2 - WallC.ty1;
ds_p->WallDepthScale = WallDepthScale; ds_p->tmapvals = WallT;
ds_p->WallDepthOrg = WallDepthOrg; ds_p->siz1 = (DWORD)DivScale32 (1, WallC.sz1) >> 1;
ds_p->WallUoverZorg = WallUoverZorg; ds_p->siz2 = (DWORD)DivScale32 (1, WallC.sz2) >> 1;
ds_p->WallUoverZstep = WallUoverZstep;
ds_p->WallInvZorg = WallInvZorg;
ds_p->WallInvZstep = WallInvZstep;
ds_p->siz1 = (DWORD)DivScale32 (1, WallSZ1) >> 1;
ds_p->siz2 = (DWORD)DivScale32 (1, WallSZ2) >> 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;
@ -2465,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()) &&
(WallSZ1 >= TOO_CLOSE_Z && WallSZ2 >= 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;
@ -2607,65 +2584,65 @@ void R_StoreWallRange (int start, int stop)
ds_p++; ds_p++;
} }
int OWallMost (short *mostbuf, fixed_t z) int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc)
{ {
int bad, y, ix1, ix2, iy1, iy2; int bad, y, ix1, ix2, iy1, iy2;
fixed_t s1, s2, s3, s4; fixed_t s1, s2, s3, s4;
z = -(z >> 4); z = -(z >> 4);
s1 = MulScale16 (globaluclip, WallSZ1); s2 = MulScale16 (globaluclip, WallSZ2); s1 = MulScale16 (globaluclip, wallc->sz1); s2 = MulScale16 (globaluclip, wallc->sz2);
s3 = MulScale16 (globaldclip, WallSZ1); s4 = MulScale16 (globaldclip, WallSZ2); 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[WallSX1], 0, (WallSX2 - WallSX1)*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[WallSX1], WallSX2 - WallSX1, viewheight); clearbufshort (&mostbuf[wallc->sx1], wallc->sx2 - wallc->sx1, viewheight);
return bad; return bad;
} }
#endif #endif
ix1 = WallSX1; iy1 = WallSZ1; ix1 = wallc->sx1; iy1 = wallc->sz1;
ix2 = WallSX2; iy2 = WallSZ2; 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 = WallSZ1 + MulScale30 (WallSZ2 - WallSZ1, t); int inty = wallc->sz1 + MulScale30 (wallc->sz2 - wallc->sz1, t);
int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2 - WallSX1, inty); int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2 - wallc->sx1, inty);
if ((bad & 3) == 2) if ((bad & 3) == 2)
{ {
if (WallSX1 <= xcross) { iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; }
if (WallSX2 > xcross) memset (&mostbuf[xcross], 0, (WallSX2-xcross)*sizeof(mostbuf[0])); if (wallc->sx2 > xcross) memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0]));
} }
else else
{ {
if (xcross <= WallSX2) { iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; }
if (xcross > WallSX1) memset (&mostbuf[WallSX1], 0, (xcross-WallSX1)*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 = WallSZ1 + MulScale30 (WallSZ2 - WallSZ1, t); int inty = wallc->sz1 + MulScale30 (wallc->sz2 - wallc->sz1, t);
int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2 - WallSX1, inty); int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2 - wallc->sx1, inty);
if ((bad & 12) == 8) if ((bad & 12) == 8)
{ {
if (WallSX1 <= xcross) { iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; }
if (WallSX2 > xcross) clearbufshort (&mostbuf[xcross], WallSX2 - xcross, viewheight); if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2 - xcross, viewheight);
} }
else else
{ {
if (xcross <= WallSX2) { iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; }
if (xcross > WallSX1) clearbufshort (&mostbuf[WallSX1], xcross - WallSX1, viewheight); if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross - wallc->sx1, viewheight);
} }
} }
@ -2683,12 +2660,12 @@ int OWallMost (short *mostbuf, fixed_t z)
double max = viewheight; double max = viewheight;
double zz = z / 65536.0; double zz = z / 65536.0;
#if 0 #if 0
double z1 = zz * InvZtoScale / WallSZ1; double z1 = zz * InvZtoScale / wallc->sz1;
double z2 = zz * InvZtoScale / WallSZ2 - z1; double z2 = zz * InvZtoScale / wallc->sz2 - z1;
z2 /= (WallSX2 - WallSX1); z2 /= (wallc->sx2 - wallc->sx1);
z1 += centeryfrac / 65536.0; z1 += centeryfrac / 65536.0;
for (int x = WallSX1; x < WallSX2; ++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;
@ -2696,18 +2673,18 @@ int OWallMost (short *mostbuf, fixed_t z)
#else #else
double top, bot, i; double top, bot, i;
i = WallSX1 - centerx; i = wallc->sx1 - centerx;
top = WallUoverZorg + WallUoverZstep * i; top = WallT.UoverZorg + WallT.UoverZstep * i;
bot = WallInvZorg + WallInvZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i;
double cy = centeryfrac / 65536.0; double cy = centeryfrac / 65536.0;
for (int x = WallSX1; x < WallSX2; x++) for (int x = wallc->sx1; x < wallc->sx2; x++)
{ {
double frac = top / bot; double frac = top / bot;
double scale = frac * WallDepthScale + WallDepthOrg; double scale = frac * WallT.DepthScale + WallT.DepthOrg;
mostbuf[x] = xs_RoundToInt(clamp(zz / scale + cy, 0.0, max)); mostbuf[x] = xs_RoundToInt(clamp(zz / scale + cy, 0.0, max));
top += WallUoverZstep; top += WallT.UoverZstep;
bot += WallInvZstep; bot += WallT.InvZstep;
} }
#endif #endif
#endif #endif
@ -2719,11 +2696,11 @@ int OWallMost (short *mostbuf, fixed_t z)
return bad; return bad;
} }
int WallMost (short *mostbuf, const secplane_t &plane) int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc)
{ {
if ((plane.a | plane.b) == 0) if ((plane.a | plane.b) == 0)
{ {
return OWallMost (mostbuf, ((plane.c < 0) ? plane.d : -plane.d) - viewz); return OWallMost (mostbuf, ((plane.c < 0) ? plane.d : -plane.d) - viewz, wallc);
} }
fixed_t x, y, den, z1, z2, oz1, oz2; fixed_t x, y, den, z1, z2, oz1, oz2;
@ -2734,21 +2711,21 @@ int WallMost (short *mostbuf, const secplane_t &plane)
{ {
x = curline->v2->x; x = curline->v2->x;
y = curline->v2->y; y = curline->v2->y;
if (WallSX1 == 0 && 0 != (den = WallTX1 - WallTX2 + WallTY1 - WallTY2)) if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2))
{ {
int frac = SafeDivScale30 (WallTY1 + WallTX1, 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 (WallSX2 > WallSX1 + 1) if (wallc->sx2 > wallc->sx1 + 1)
{ {
x = curline->v1->x; x = curline->v1->x;
y = curline->v1->y; y = curline->v1->y;
if (WallSX2 == viewwidth && 0 != (den = WallTX1 - WallTX2 - WallTY1 + WallTY2)) if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2))
{ {
int frac = SafeDivScale30 (WallTY2 - WallTX2, 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);
} }
@ -2763,21 +2740,21 @@ int WallMost (short *mostbuf, const secplane_t &plane)
{ {
x = curline->v1->x; x = curline->v1->x;
y = curline->v1->y; y = curline->v1->y;
if (WallSX1 == 0 && 0 != (den = WallTX1 - WallTX2 + WallTY1 - WallTY2)) if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2))
{ {
int frac = SafeDivScale30 (WallTY1 + WallTX1, 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 (WallSX2 > WallSX1 + 1) if (wallc->sx2 > wallc->sx1 + 1)
{ {
x = curline->v2->x; x = curline->v2->x;
y = curline->v2->y; y = curline->v2->y;
if (WallSX2 == viewwidth && 0 != (den = WallTX1 - WallTX2 - WallTY1 + WallTY2)) if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2))
{ {
int frac = SafeDivScale30 (WallTY2 - WallTX2, 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);
} }
@ -2789,12 +2766,12 @@ int WallMost (short *mostbuf, const secplane_t &plane)
} }
} }
s1 = MulScale12 (globaluclip, WallSZ1); s2 = MulScale12 (globaluclip, WallSZ2); s1 = MulScale12 (globaluclip, wallc->sz1); s2 = MulScale12 (globaluclip, wallc->sz2);
s3 = MulScale12 (globaldclip, WallSZ1); s4 = MulScale12 (globaldclip, WallSZ2); 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 = WallSX1; ix2 = WallSX2; ix1 = wallc->sx1; ix2 = wallc->sx2;
iy1 = WallSZ1; iy2 = WallSZ2; iy1 = wallc->sz1; iy2 = wallc->sz2;
oz1 = z1; oz2 = z2; oz1 = z1; oz2 = z2;
if ((bad&3) == 3) if ((bad&3) == 3)
@ -2814,9 +2791,9 @@ int WallMost (short *mostbuf, const secplane_t &plane)
{ {
//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 = WallSZ1 + MulScale30 (WallSZ2-WallSZ1,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 = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2-WallSX1, 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);
@ -2824,13 +2801,13 @@ int WallMost (short *mostbuf, const secplane_t &plane)
if ((bad&3) == 2) if ((bad&3) == 2)
{ {
if (WallSX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; }
memset (&mostbuf[xcross], 0, (WallSX2-xcross)*sizeof(mostbuf[0])); memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0]));
} }
else else
{ {
if (xcross <= WallSX2) { z1 = intz; iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; }
memset (&mostbuf[WallSX1], 0, (xcross-WallSX1)*sizeof(mostbuf[0])); memset (&mostbuf[wallc->sx1], 0, (xcross-wallc->sx1)*sizeof(mostbuf[0]));
} }
} }
@ -2838,9 +2815,9 @@ int WallMost (short *mostbuf, const secplane_t &plane)
{ {
//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 = WallSZ1 + MulScale30 (WallSZ2-WallSZ1,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 = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2-WallSX1,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);
@ -2848,13 +2825,13 @@ int WallMost (short *mostbuf, const secplane_t &plane)
if ((bad&12) == 8) if ((bad&12) == 8)
{ {
if (WallSX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; }
if (WallSX2 > xcross) clearbufshort (&mostbuf[xcross], WallSX2-xcross, viewheight); if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2-xcross, viewheight);
} }
else else
{ {
if (xcross <= WallSX2) { z1 = intz; iy1 = inty; ix1 = xcross; } if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; }
if (xcross > WallSX1) clearbufshort (&mostbuf[WallSX1], xcross-WallSX1, viewheight); if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross-wallc->sx1, viewheight);
} }
} }
@ -2877,16 +2854,16 @@ int WallMost (short *mostbuf, const secplane_t &plane)
return bad; return bad;
} }
static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat, int x1, int x2)
{ {
// fix for rounding errors // fix for rounding errors
walxrepeat = abs(walxrepeat); walxrepeat = abs(walxrepeat);
fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0; fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0;
int x; int x;
if (WallSX1 > 0) if (x1 > 0)
{ {
for (x = WallSX1; x < WallSX2; x++) for (x = x1; x < x2; x++)
{ {
if ((unsigned)lwall[x] >= (unsigned)walxrepeat) if ((unsigned)lwall[x] >= (unsigned)walxrepeat)
{ {
@ -2899,7 +2876,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat)
} }
} }
fix = walxrepeat - 1 - fix; fix = walxrepeat - 1 - fix;
for (x = WallSX2-1; x >= WallSX1; x--) for (x = x2-1; x >= x1; x--)
{ {
if ((unsigned)lwall[x] >= (unsigned)walxrepeat) if ((unsigned)lwall[x] >= (unsigned)walxrepeat)
{ {
@ -2912,16 +2889,16 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat)
} }
} }
void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2)
{ // swall = scale, lwall = texturecolumn { // swall = scale, lwall = texturecolumn
double top, bot, i; double top, bot, i;
double xrepeat = fabs((double)walxrepeat); double xrepeat = fabs((double)walxrepeat);
i = WallSX1 - centerx; i = x1 - centerx;
top = WallUoverZorg + WallUoverZstep * i; top = WallT.UoverZorg + WallT.UoverZstep * i;
bot = WallInvZorg + WallInvZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i;
for (int x = WallSX1; x < WallSX2; x++) for (int x = x1; x < x2; x++)
{ {
double frac = top / bot; double frac = top / bot;
if (walxrepeat < 0) if (walxrepeat < 0)
@ -2932,27 +2909,27 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat)
{ {
lwall[x] = xs_RoundToInt(frac * xrepeat); lwall[x] = xs_RoundToInt(frac * xrepeat);
} }
swall[x] = xs_RoundToInt(frac * WallDepthScale + WallDepthOrg); swall[x] = xs_RoundToInt(frac * WallT.DepthScale + WallT.DepthOrg);
top += WallUoverZstep; top += WallT.UoverZstep;
bot += WallInvZstep; bot += WallT.InvZstep;
} }
PrepWallRoundFix(lwall, walxrepeat); PrepWallRoundFix(lwall, walxrepeat, x1, x2);
} }
void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2)
{ // lwall = texturecolumn { // lwall = texturecolumn
double top, bot, i; double top, bot, i;
double xrepeat = fabs((double)walxrepeat); double xrepeat = fabs((double)walxrepeat);
double topstep; double topstep;
i = WallSX1 - centerx; i = x1 - centerx;
top = WallUoverZorg + WallUoverZstep * i; top = WallT.UoverZorg + WallT.UoverZstep * i;
bot = WallInvZorg + WallInvZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i;
top *= xrepeat; top *= xrepeat;
topstep = WallUoverZstep * xrepeat; topstep = WallT.UoverZstep * xrepeat;
for (int x = WallSX1; x < WallSX2; x++) for (int x = x1; x < x2; x++)
{ {
if (walxrepeat < 0) if (walxrepeat < 0)
{ {
@ -2963,9 +2940,9 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat)
lwall[x] = xs_RoundToInt(top / bot); lwall[x] = xs_RoundToInt(top / bot);
} }
top += topstep; top += topstep;
bot += WallInvZstep; bot += WallT.InvZstep;
} }
PrepWallRoundFix(lwall, walxrepeat); PrepWallRoundFix(lwall, walxrepeat, x1, x2);
} }
// pass = 0: when seg is first drawn // pass = 0: when seg is first drawn
@ -3044,14 +3021,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
// to a wall, we use the wall's angle instead of the decal's. This is // to a wall, we use the wall's angle instead of the decal's. This is
// pretty much the same as what R_AddLine() does. // pretty much the same as what R_AddLine() does.
fixed_t savetx1, savetx2, savety1, savety2, savesz1, savesz2; FWallCoords savecoord = WallC;
savetx1 = WallTX1;
savetx2 = WallTX2;
savety1 = WallTY1;
savety2 = WallTY2;
savesz1 = WallSZ1;
savesz2 = WallSZ2;
x2 = WallSpriteTile->GetWidth(); x2 = WallSpriteTile->GetWidth();
x1 = WallSpriteTile->LeftOffset; x1 = WallSpriteTile->LeftOffset;
@ -3068,76 +3038,16 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
ly = decaly - FixedMul (x1, finesine[ang]) - viewy; ly = decaly - FixedMul (x1, finesine[ang]) - viewy;
ly2 = decaly + FixedMul (x2, finesine[ang]) - viewy; ly2 = decaly + FixedMul (x2, finesine[ang]) - viewy;
WallTX1 = DMulScale20 (lx, viewsin, -ly, viewcos); if (WallC.Init(lx, ly, lx2, ly2, TOO_CLOSE_Z))
WallTX2 = DMulScale20 (lx2, viewsin, -ly2, viewcos);
WallTY1 = DMulScale20 (lx, viewtancos, ly, viewtansin);
WallTY2 = DMulScale20 (lx2, viewtancos, ly2, viewtansin);
if (MirrorFlags & RF_XFLIP)
{
int t = 256-WallTX1;
WallTX1 = 256-WallTX2;
WallTX2 = t;
swapvalues (WallTY1, WallTY2);
}
if (WallTX1 >= -WallTY1)
{
if (WallTX1 > WallTY1) goto done; // left edge is off the right side
if (WallTY1 == 0) goto done;
x1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS;
if (WallTX1 >= 0) x1 = MIN (viewwidth, x1+1); // fix for signed divide
WallSZ1 = WallTY1;
}
else
{
if (WallTX2 < -WallTY2) goto done; // wall is off the left side
fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1;
if (den == 0) goto done;
x1 = 0;
WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den);
}
if (WallSZ1 < TOO_CLOSE_Z)
goto done; goto done;
if (WallTX2 <= WallTY2) x1 = WallC.sx1;
{ x2 = WallC.sx2;
if (WallTX2 < -WallTY2) goto done; // right edge is off the left side
if (WallTY2 == 0) goto done;
x2 = (centerxfrac + Scale (WallTX2, centerxfrac, WallTY2)) >> FRACBITS;
if (WallTX2 >= 0) x2 = MIN (viewwidth, x2+1); // fix for signed divide
WallSZ2 = WallTY2;
}
else
{
if (WallTX1 > WallTY1) goto done; // wall is off the right side
fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1;
if (den == 0) goto done;
x2 = viewwidth;
WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den);
}
if (x1 >= x2 || x1 > clipper->x2 || x2 <= clipper->x1 || WallSZ2 < TOO_CLOSE_Z) if (x1 > clipper->x2 || x2 <= clipper->x1)
goto done; goto done;
if (MirrorFlags & RF_XFLIP) WallT.InitFromWallCoords(&WallC);
{
WallUoverZorg = (float)WallTX2 * WallTMapScale;
WallUoverZstep = (float)(-WallTY2) * 32.f;
WallInvZorg = (float)(WallTX2 - WallTX1) * WallTMapScale;
WallInvZstep = (float)(WallTY1 - WallTY2) * 32.f;
}
else
{
WallUoverZorg = (float)WallTX1 * WallTMapScale;
WallUoverZstep = (float)(-WallTY1) * 32.f;
WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale;
WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f;
}
WallDepthScale = WallInvZstep * WallTMapScale2;
WallDepthOrg = -WallUoverZstep * WallTMapScale2;
// Get the top and bottom clipping arrays // Get the top and bottom clipping arrays
switch (decal->RenderFlags & RF_CLIPMASK) switch (decal->RenderFlags & RF_CLIPMASK)
@ -3210,11 +3120,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
goto done; goto done;
} }
swapvalues (x1, WallSX1); PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS, x1, x2);
swapvalues (x2, WallSX2);
PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS);
swapvalues (x1, WallSX1);
swapvalues (x2, WallSX2);
if (flipx) if (flipx)
{ {
@ -3239,7 +3145,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
rereadcolormap = false; rereadcolormap = false;
} }
rw_light = rw_lightleft + (x1 - WallSX1) * 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)
@ -3300,8 +3206,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{ // calculate lighting { // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
} }
R_WallSpriteColumn (R_DrawMaskedColumn);
WallSpriteColumn (R_DrawMaskedColumn);
dc_x++; dc_x++;
} }
@ -3314,7 +3219,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
rt_initcols(); rt_initcols();
for (int zz = 4; zz; --zz) for (int zz = 4; zz; --zz)
{ {
WallSpriteColumn (R_DrawMaskedColumnHoriz); R_WallSpriteColumn (R_DrawMaskedColumnHoriz);
dc_x++; dc_x++;
} }
rt_draw4cols (dc_x - 4); rt_draw4cols (dc_x - 4);
@ -3326,8 +3231,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{ // calculate lighting { // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
} }
R_WallSpriteColumn (R_DrawMaskedColumn);
WallSpriteColumn (R_DrawMaskedColumn);
dc_x++; dc_x++;
} }
} }
@ -3346,28 +3250,5 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
R_FinishSetPatchStyle (); R_FinishSetPatchStyle ();
done: done:
WallTX1 = savetx1; WallC = savecoord;
WallTX2 = savetx2;
WallTY1 = savety1;
WallTY2 = savety2;
WallSZ1 = savesz1;
WallSZ2 = savesz2;
}
static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans))
{
unsigned int texturecolumn = lwall[dc_x] >> FRACBITS;
dc_iscale = MulScale16 (swall[dc_x], rw_offset);
spryscale = SafeDivScale32 (1, dc_iscale);
if (sprflipvert)
sprtopscreen = centeryfrac + FixedMul (dc_texturemid, spryscale);
else
sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale);
const BYTE *column;
const FTexture::Span *spans;
column = WallSpriteTile->GetColumn (texturecolumn, &spans);
dc_texturefrac = 0;
drawfunc (column, spans);
rw_light += rw_lightstep;
} }

View File

@ -31,10 +31,22 @@ extern short *openings;
extern ptrdiff_t lastopening; extern ptrdiff_t lastopening;
extern size_t maxopenings; extern size_t maxopenings;
int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc);
int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc);
void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2);
void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2);
ptrdiff_t R_NewOpening (ptrdiff_t len); ptrdiff_t R_NewOpening (ptrdiff_t len);
void R_CheckDrawSegs (); void R_CheckDrawSegs ();
void R_RenderSegLoop (); void R_RenderSegLoop ();
extern fixed_t swall[MAXWIDTH];
extern fixed_t lwall[MAXWIDTH];
extern fixed_t rw_light; // [RH] Scale lights with viewsize adjustments
extern fixed_t rw_lightstep;
extern fixed_t rw_lightleft;
extern fixed_t rw_offset;
#endif #endif

View File

@ -40,7 +40,6 @@
#include "r_bsp.h" #include "r_bsp.h"
#include "r_swrenderer.h" #include "r_swrenderer.h"
#include "r_3dfloors.h" #include "r_3dfloors.h"
#include "r_polymost.h"
#include "textures/textures.h" #include "textures/textures.h"
#include "r_data/voxels.h" #include "r_data/voxels.h"
@ -49,7 +48,6 @@ class FArchive;
void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio); void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio);
void R_SetupColormap(player_t *); void R_SetupColormap(player_t *);
void R_SetupFreelook(); void R_SetupFreelook();
void R_SetupPolymost();
void R_InitRenderer(); void R_InitRenderer();
extern float LastFOV; extern float LastFOV;
@ -245,7 +243,6 @@ void FSoftwareRenderer::SetupFrame(player_t *player)
{ {
R_SetupColormap(player); R_SetupColormap(player);
R_SetupFreelook(); R_SetupFreelook();
R_SetupPolymost();
} }
//========================================================================== //==========================================================================

View File

@ -114,6 +114,8 @@ FDynamicColormap *VisPSpritesBaseColormap[NUMPSPRITES];
static int spriteshade; static int spriteshade;
FTexture *WallSpriteTile;
// constant arrays // constant arrays
// used for psprite clipping and initializing clipping // used for psprite clipping and initializing clipping
short zeroarray[MAXWIDTH]; short zeroarray[MAXWIDTH];
@ -145,6 +147,8 @@ static vissprite_t **spritesorter;
static int spritesortersize = 0; static int spritesortersize = 0;
static int vsprcount; static int vsprcount;
static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, INTBOOL flip);
void R_DeinitSprites() void R_DeinitSprites()
{ {
@ -401,6 +405,154 @@ void R_DrawVisSprite (vissprite_t *vis)
NetUpdate (); NetUpdate ();
} }
void R_DrawWallSprite(vissprite_t *spr)
{
int x1, x2;
fixed_t yscale;
x1 = MAX<int>(spr->x1, spr->wallc.sx1);
x2 = MIN<int>(spr->x2 + 1, spr->wallc.sx2 + 1);
if (x1 >= x2)
return;
WallT.InitFromWallCoords(&spr->wallc);
PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2);
yscale = spr->yscale;
dc_texturemid = FixedDiv(spr->gzt - viewz, yscale);
if (spr->renderflags & RF_XFLIP)
{
int right = (spr->pic->GetWidth() << FRACBITS) - 1;
for (int i = x1; i < x2; i++)
{
lwall[i] = right - lwall[i];
}
}
// Prepare lighting
bool calclighting = false;
FDynamicColormap *usecolormap = basecolormap;
bool rereadcolormap = true;
// Decals that are added to the scene must fade to black.
if (spr->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
{
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
rereadcolormap = false;
}
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)
dc_colormap = usecolormap->Maps + fixedlightlev;
else if (fixedcolormap != NULL)
dc_colormap = fixedcolormap;
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
dc_colormap = usecolormap->Maps;
else
calclighting = true;
// Draw it
WallSpriteTile = spr->pic;
if (spr->renderflags & RF_YFLIP)
{
sprflipvert = true;
yscale = -yscale;
dc_texturemid = dc_texturemid - (spr->pic->GetHeight() << FRACBITS);
}
else
{
sprflipvert = false;
}
// rw_offset is used as the texture's vertical scale
rw_offset = SafeDivScale30(1, yscale);
dc_x = x1;
ESPSResult mode;
mode = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.alpha, spr->Translation, spr->FillColor);
// R_SetPatchStyle can modify basecolormap.
if (rereadcolormap)
{
usecolormap = basecolormap;
}
if (mode == DontDraw)
{
return;
}
else
{
int stop4;
if (mode == DoDraw0)
{ // 1 column at a time
stop4 = dc_x;
}
else // DoDraw1
{ // up to 4 columns at a time
stop4 = x2 & ~3;
}
while ((dc_x < stop4) && (dc_x & 3))
{
if (calclighting)
{ // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT);
}
R_WallSpriteColumn(R_DrawMaskedColumn);
dc_x++;
}
while (dc_x < stop4)
{
if (calclighting)
{ // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT);
}
rt_initcols();
for (int zz = 4; zz; --zz)
{
R_WallSpriteColumn(R_DrawMaskedColumnHoriz);
dc_x++;
}
rt_draw4cols(dc_x - 4);
}
while (dc_x < x2)
{
if (calclighting)
{ // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT);
}
R_WallSpriteColumn(R_DrawMaskedColumn);
dc_x++;
}
}
R_FinishSetPatchStyle();
}
void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans))
{
unsigned int texturecolumn = lwall[dc_x] >> FRACBITS;
dc_iscale = MulScale16 (swall[dc_x], rw_offset);
spryscale = SafeDivScale32 (1, dc_iscale);
if (sprflipvert)
sprtopscreen = centeryfrac + FixedMul (dc_texturemid, spryscale);
else
sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale);
const BYTE *column;
const FTexture::Span *spans;
column = WallSpriteTile->GetColumn (texturecolumn, &spans);
dc_texturefrac = 0;
drawfunc (column, spans);
rw_light += rw_lightstep;
}
void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop, short *clipbot) void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop, short *clipbot)
{ {
ESPSResult mode; ESPSResult mode;
@ -521,12 +673,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY); fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY);
fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ) + thing->GetBobOffset(r_TicFrac); fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ) + thing->GetBobOffset(r_TicFrac);
// transform the origin point
tr_x = fx - viewx;
tr_y = fy - viewy;
tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin);
tex = NULL; tex = NULL;
voxel = NULL; voxel = NULL;
@ -618,6 +764,18 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
return; return;
} }
if ((thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
{
R_ProjectWallSprite(thing, fx, fy, fz, picnum, spritescaleX, spritescaleY, flip);
return;
}
// transform the origin point
tr_x = fx - viewx;
tr_y = fy - viewy;
tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin);
// thing is behind view plane? // thing is behind view plane?
if (voxel == NULL && tz < MINZ) if (voxel == NULL && tz < MINZ)
return; return;
@ -782,7 +940,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
vis->heightsec = heightsec; vis->heightsec = heightsec;
vis->sector = thing->Sector; vis->sector = thing->Sector;
vis->cx = tx2;
vis->depth = tz; vis->depth = tz;
vis->gx = fx; vis->gx = fx;
vis->gy = fy; vis->gy = fy;
@ -807,12 +964,14 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
{ {
vis->voxel = voxel->Voxel; vis->voxel = voxel->Voxel;
vis->bIsVoxel = true; vis->bIsVoxel = true;
vis->bWallSprite = false;
DrewAVoxel = true; DrewAVoxel = true;
} }
else else
{ {
vis->pic = tex; vis->pic = tex;
vis->bIsVoxel = false; vis->bIsVoxel = false;
vis->bWallSprite = false;
} }
// The software renderer cannot invert the source without inverting the overlay // The software renderer cannot invert the source without inverting the overlay
@ -874,6 +1033,79 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
} }
} }
static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, INTBOOL flip)
{
FWallCoords wallc;
int x1, x2;
fixed_t lx1, lx2, ly1, ly2;
fixed_t gzb, gzt, tz;
FTexture *pic = TexMan(picnum, true);
angle_t ang = (thing->angle + ANGLE_90) >> ANGLETOFINESHIFT;
vissprite_t *vis;
// Determine left and right edges of sprite. The sprite's angle is its normal,
// so the edges are 90 degrees each side of it.
x2 = pic->GetScaledWidth();
x1 = pic->GetScaledLeftOffset();
x1 *= xscale;
x2 *= xscale;
lx1 = fx - FixedMul(x1, finecosine[ang]) - viewx;
ly1 = fy - FixedMul(x1, finesine[ang]) - viewy;
lx2 = lx1 + FixedMul(x2, finecosine[ang]);
ly2 = ly1 + FixedMul(x2, finesine[ang]);
// Is it off-screen?
if (wallc.Init(lx1, ly1, lx2, ly2, TOO_CLOSE_Z))
return;
if (wallc.sx1 > WindowRight || wallc.sx2 <= WindowLeft)
return;
// Sprite sorting should probably treat these as walls, not sprites,
// but right now, I just want to get them drawing.
tz = DMulScale20(fx - viewx, viewtancos, fy - viewy, viewtansin);
int scaled_to = pic->GetScaledTopOffset();
int scaled_bo = scaled_to - pic->GetScaledHeight();
gzt = fz + yscale * scaled_to;
gzb = fz + yscale * scaled_bo;
vis = R_NewVisSprite();
vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1;
vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2-1;
vis->yscale = yscale;
vis->idepth = (unsigned)DivScale32(1, tz) >> 1;
vis->depth = tz;
vis->sector = thing->Sector;
vis->heightsec = NULL;
vis->gx = fx;
vis->gy = fy;
vis->gz = fz;
vis->gzb = gzb;
vis->gzt = gzt;
vis->deltax = fx - viewx;
vis->deltay = fy - viewy;
vis->renderflags = thing->renderflags;
if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D
vis->Style.RenderStyle = thing->RenderStyle;
vis->FillColor = thing->fillcolor;
vis->Translation = thing->Translation;
vis->FakeFlatStat = 0;
vis->Style.alpha = thing->alpha;
vis->fakefloor = NULL;
vis->fakeceiling = NULL;
vis->ColormapNum = 0;
vis->bInMirror = MirrorFlags & RF_XFLIP;
vis->pic = pic;
vis->bIsVoxel = false;
vis->bWallSprite = true;
vis->ColormapNum = GETPALOOKUP(
(fixed_t)DivScale12 (r_SpriteVisibility, MAX(tz, MINZ)), spriteshade);
vis->Style.colormap = basecolormap->Maps + (vis->ColormapNum << COLORMAPSHIFT);
vis->wallc = wallc;
}
// //
// R_AddSprites // R_AddSprites
@ -1845,16 +2077,19 @@ void R_DrawSprite (vissprite_t *spr)
r2 = MIN<int> (ds->x2, x2); r2 = MIN<int> (ds->x2, x2);
fixed_t neardepth, fardepth; fixed_t neardepth, fardepth;
if (ds->sz1 < ds->sz2) if (!spr->bWallSprite)
{ {
neardepth = ds->sz1, fardepth = ds->sz2; if (ds->sz1 < ds->sz2)
{
neardepth = ds->sz1, fardepth = ds->sz2;
}
else
{
neardepth = ds->sz2, fardepth = ds->sz1;
}
} }
else // Check if sprite is in front of draw seg:
{ if ((!spr->bWallSprite && neardepth > spr->depth) || ((spr->bWallSprite || fardepth > spr->depth) &&
neardepth = ds->sz2, fardepth = ds->sz1;
}
if (neardepth > spr->depth || (fardepth > spr->depth &&
// Check if sprite is in front of draw seg:
DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x, 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))
{ {
@ -1904,7 +2139,14 @@ void R_DrawSprite (vissprite_t *spr)
{ {
mfloorclip = clipbot; mfloorclip = clipbot;
mceilingclip = cliptop; mceilingclip = cliptop;
R_DrawVisSprite (spr); if (!spr->bWallSprite)
{
R_DrawVisSprite(spr);
}
else
{
R_DrawWallSprite(spr);
}
} }
else else
{ {
@ -2161,7 +2403,6 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
vis->yscale = xscale; vis->yscale = xscale;
vis->depth = tz; vis->depth = tz;
vis->idepth = (DWORD)DivScale32 (1, tz) >> 1; vis->idepth = (DWORD)DivScale32 (1, tz) >> 1;
vis->cx = tx;
vis->gx = particle->x; vis->gx = particle->x;
vis->gy = particle->y; vis->gy = particle->y;
vis->gz = particle->z; // kg3D vis->gz = particle->z; // kg3D

View File

@ -23,6 +23,7 @@
#ifndef __R_THINGS__ #ifndef __R_THINGS__
#define __R_THINGS__ #define __R_THINGS__
#include "r_bsp.h"
// A vissprite_t is a thing // A vissprite_t is a thing
// that will be drawn during a refresh. // that will be drawn during a refresh.
@ -31,7 +32,6 @@
struct vissprite_t struct vissprite_t
{ {
short x1, x2; short x1, x2;
fixed_t cx; // for line side calculation
fixed_t gx, gy, gz; // origin in world coordinates fixed_t gx, gy, gz; // origin in world coordinates
angle_t angle; angle_t angle;
fixed_t gzb, gzt; // global bottom / top for silhouette clipping fixed_t gzb, gzt; // global bottom / top for silhouette clipping
@ -43,18 +43,26 @@ struct vissprite_t
fixed_t floorclip; fixed_t floorclip;
union union
{ {
// Used by regular sprites FTexture *pic;
struct FVoxel *voxel;
};
union
{
// Used by face sprites
struct struct
{ {
FTexture *pic;
fixed_t texturemid; fixed_t texturemid;
fixed_t startfrac; // horizontal position of x1 fixed_t startfrac; // horizontal position of x1
fixed_t xiscale; // negative if flipped fixed_t xiscale; // negative if flipped
}; };
// Used by wall sprites
struct
{
FWallCoords wallc;
};
// Used by voxels // Used by voxels
struct struct
{ {
struct FVoxel *voxel;
fixed_t vx, vy, vz; // view origin fixed_t vx, vy, vz; // view origin
angle_t vang; // view angle angle_t vang; // view angle
}; };
@ -64,6 +72,7 @@ struct vissprite_t
F3DFloor *fakefloor; F3DFloor *fakefloor;
F3DFloor *fakeceiling; F3DFloor *fakeceiling;
BYTE bIsVoxel:1; // [RH] Use voxel instead of pic BYTE bIsVoxel:1; // [RH] Use voxel instead of pic
BYTE bWallSprite:1; // [RH] This is a wall sprite
BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg
BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror
BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on
@ -99,9 +108,11 @@ extern fixed_t pspritexscale;
extern fixed_t pspriteyscale; extern fixed_t pspriteyscale;
extern fixed_t pspritexiscale; extern fixed_t pspritexiscale;
extern FTexture *WallSpriteTile;
void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *spans); void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *spans);
void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans));
void R_CacheSprite (spritedef_t *sprite); void R_CacheSprite (spritedef_t *sprite);
void R_SortVisSprites (int (STACK_ARGS *compare)(const void *, const void *), size_t first); void R_SortVisSprites (int (STACK_ARGS *compare)(const void *, const void *), size_t first);

View File

@ -289,8 +289,8 @@ bool F7ZFile::Open(bool quiet)
continue; continue;
} }
nameUTF16.Resize(nameLength); nameUTF16.Resize((unsigned)nameLength);
nameASCII.Resize(nameLength); nameASCII.Resize((unsigned)nameLength);
SzArEx_GetFileNameUtf16(&Archive->DB, i, &nameUTF16[0]); SzArEx_GetFileNameUtf16(&Archive->DB, i, &nameUTF16[0]);
for (size_t c = 0; c < nameLength; ++c) for (size_t c = 0; c < nameLength; ++c)
{ {

View File

@ -511,8 +511,6 @@ int S_AddSoundLump (const char *logicalname, int lump)
newsfx.LimitRange = 256*256; newsfx.LimitRange = 256*256;
newsfx.bRandomHeader = false; newsfx.bRandomHeader = false;
newsfx.bPlayerReserve = false; newsfx.bPlayerReserve = false;
newsfx.bForce11025 = false;
newsfx.bForce22050 = false;
newsfx.bLoadRAW = false; newsfx.bLoadRAW = false;
newsfx.bPlayerCompat = false; newsfx.bPlayerCompat = false;
newsfx.b16bit = false; newsfx.b16bit = false;
@ -520,6 +518,7 @@ int S_AddSoundLump (const char *logicalname, int lump)
newsfx.bSingular = false; newsfx.bSingular = false;
newsfx.bTentative = false; newsfx.bTentative = false;
newsfx.bPlayerSilent = false; newsfx.bPlayerSilent = false;
newsfx.RawRate = 0;
newsfx.link = sfxinfo_t::NO_LINK; newsfx.link = sfxinfo_t::NO_LINK;
newsfx.Rolloff.RolloffType = ROLLOFF_Doom; newsfx.Rolloff.RolloffType = ROLLOFF_Doom;
newsfx.Rolloff.MinDistance = 0; newsfx.Rolloff.MinDistance = 0;
@ -1414,13 +1413,17 @@ static void S_AddBloodSFX (int lumpnum)
{ {
const char *name = Wads.GetLumpFullName(lumpnum); const char *name = Wads.GetLumpFullName(lumpnum);
sfxnum = S_AddSound(name, rawlump); sfxnum = S_AddSound(name, rawlump);
if (sfx->Format == 5) if (sfx->Format < 5 || sfx->Format > 12)
{ { // [0..4] + invalid formats
S_sfx[sfxnum].bForce22050 = true; S_sfx[sfxnum].RawRate = 11025;
} }
else // I don't know any other formats for this else if (sfx->Format < 9)
{ { // [5..8]
S_sfx[sfxnum].bForce11025 = true; S_sfx[sfxnum].RawRate = 22050;
}
else
{ // [9..12]
S_sfx[sfxnum].RawRate = 44100;
} }
S_sfx[sfxnum].bLoadRAW = true; S_sfx[sfxnum].bLoadRAW = true;
S_sfx[sfxnum].LoopStart = LittleLong(sfx->LoopStart); S_sfx[sfxnum].LoopStart = LittleLong(sfx->LoopStart);
@ -1433,7 +1436,7 @@ static void S_AddBloodSFX (int lumpnum)
ambient->periodmax = 0; ambient->periodmax = 0;
ambient->volume = 1; ambient->volume = 1;
ambient->attenuation = 1; ambient->attenuation = 1;
ambient->sound = name; ambient->sound = FSoundID(sfxnum);
} }
} }
@ -2231,7 +2234,7 @@ void AAmbientSound::BeginPlay ()
// //
// AmbientSound :: Activate // AmbientSound :: Activate
// //
// Starts playing a sound (or does nothing of the sound is already playing). // Starts playing a sound (or does nothing if the sound is already playing).
// //
//========================================================================== //==========================================================================

View File

@ -49,8 +49,6 @@ struct sfxinfo_t
WORD bRandomHeader:1; WORD bRandomHeader:1;
WORD bPlayerReserve:1; WORD bPlayerReserve:1;
WORD bForce11025:1;
WORD bForce22050:1;
WORD bLoadRAW:1; WORD bLoadRAW:1;
WORD bPlayerCompat:1; WORD bPlayerCompat:1;
WORD b16bit:1; WORD b16bit:1;
@ -59,6 +57,8 @@ struct sfxinfo_t
WORD bTentative:1; WORD bTentative:1;
WORD bPlayerSilent:1; // This player sound is intentionally silent. WORD bPlayerSilent:1; // This player sound is intentionally silent.
WORD RawRate; // Sample rate to use when bLoadRAW is true
int LoopStart; // -1 means no specific loop defined int LoopStart; // -1 means no specific loop defined
unsigned int link; unsigned int link;

View File

@ -540,7 +540,7 @@ bool MIDIStreamer::IsPlaying()
void MIDIStreamer::MusicVolumeChanged() void MIDIStreamer::MusicVolumeChanged()
{ {
if (MIDI->FakeVolume()) if (MIDI != NULL && MIDI->FakeVolume())
{ {
float realvolume = clamp<float>(snd_musicvolume * relative_volume, 0.f, 1.f); float realvolume = clamp<float>(snd_musicvolume * relative_volume, 0.f, 1.f);
Volume = clamp<DWORD>((DWORD)(realvolume * 65535.f), 0, 65535); Volume = clamp<DWORD>((DWORD)(realvolume * 65535.f), 0, 65535);
@ -622,7 +622,7 @@ void MIDIStreamer::FluidSettingStr(const char *setting, const char *value)
void MIDIStreamer::OutputVolume (DWORD volume) void MIDIStreamer::OutputVolume (DWORD volume)
{ {
if (MIDI->FakeVolume()) if (MIDI != NULL && MIDI->FakeVolume())
{ {
NewVolume = volume; NewVolume = volume;
VolumeChanged = true; VolumeChanged = true;

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

@ -964,6 +964,7 @@ void FTextureManager::SortTexturesByType(int start, int end)
void FTextureManager::Init() void FTextureManager::Init()
{ {
DeleteAll(); DeleteAll();
SpriteFrames.Clear();
// Init Build Tile data if it hasn't been done already // Init Build Tile data if it hasn't been done already
if (BuildTileFiles.Size() == 0) CountBuildTiles (); if (BuildTileFiles.Size() == 0) CountBuildTiles ();
FTexture::InitGrayMap(); FTexture::InitGrayMap();

View File

@ -1297,6 +1297,17 @@ DEFINE_PROPERTY(gravity, F, Actor)
defaults->gravity = i; defaults->gravity = i;
} }
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(friction, F, Actor)
{
PROP_FIXED_PARM(i, 0);
if (i < 0) I_Error ("Friction must not be negative.");
defaults->Friction = 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++;
} }

View File

@ -18,6 +18,7 @@ ACTOR Actor native //: Thinker
FloatSpeed 4 FloatSpeed 4
FloatBobPhase -1 // randomly initialize by default FloatBobPhase -1 // randomly initialize by default
Gravity 1 Gravity 1
Friction 1
DamageFactor 1.0 DamageFactor 1.0
PushFactor 0.25 PushFactor 0.25
WeaveIndexXY 0 WeaveIndexXY 0

View File

@ -14,6 +14,8 @@ const int SF_RANDOMLIGHTHIT = 4;
const int SF_RANDOMLIGHTBOTH = 6; const int SF_RANDOMLIGHTBOTH = 6;
const int SF_NOUSEAMMOMISS = 8; const int SF_NOUSEAMMOMISS = 8;
const int SF_NOUSEAMMO = 16; const int SF_NOUSEAMMO = 16;
const int SF_NOPULLIN = 32;
const int SF_NOTURN = 64;
// Flags for A_CustomMissile // Flags for A_CustomMissile
const int CMF_AIMOFFSET = 1; const int CMF_AIMOFFSET = 1;

View File

@ -39,8 +39,8 @@ ACTOR Revenant 66
SKEL I 6 A_SkelFist SKEL I 6 A_SkelFist
Goto See Goto See
Missile: Missile:
SKEL J 1 BRIGHT A_FaceTarget SKEL J 0 BRIGHT A_FaceTarget
SKEL J 9 BRIGHT A_FaceTarget SKEL J 10 BRIGHT A_FaceTarget
SKEL K 10 A_SkelMissile SKEL K 10 A_SkelMissile
SKEL K 10 A_FaceTarget SKEL K 10 A_FaceTarget
Goto See Goto See

View File

@ -1,5 +1,23 @@
// Must be sorted in identification order (easiest to recognize first!) // Must be sorted in identification order (easiest to recognize first!)
IWad
{
Name = "The Adventures of Square"
Game = "Doom"
Config = "Square"
MustContain = "SQU-IWAD", "E1A1"
BannerColors = "ff ff ff", "80 00 80"
}
IWad
{
Name = "The Adventures of Square (Square-ware)"
Game = "Doom"
Config = "Square"
MustContain = "SQU-SWE1", "E1A1"
BannerColors = "ff ff ff", "80 00 80"
}
IWad IWad
{ {
Name = "Harmony" Name = "Harmony"
@ -361,4 +379,5 @@ Names
"harm1.wad" "harm1.wad"
"hacx.wad" "hacx.wad"
"hacx2.wad" "hacx2.wad"
"square1.pk3"
} }

View File

@ -816,6 +816,7 @@ OptionMenu "AltHUDOptions"
Option "Show item count", "hud_showitems", "OnOff" Option "Show item count", "hud_showitems", "OnOff"
Option "Show stamina and accuracy", "hud_showstats", "OnOff" Option "Show stamina and accuracy", "hud_showstats", "OnOff"
Option "Show berserk", "hud_berserk_health", "OnOff" Option "Show berserk", "hud_berserk_health", "OnOff"
Option "Show weapons", "hud_showweapons", "OnOff"
Option "Show time", "hud_showtime", "AltHUDTime" Option "Show time", "hud_showtime", "AltHUDTime"
Option "Time color", "hud_timecolor", "TextColors" Option "Time color", "hud_timecolor", "TextColors"
Slider "Red ammo display below %", "hud_ammo_red", 0, 100, 1, 0 Slider "Red ammo display below %", "hud_ammo_red", 0, 100, 1, 0

View File

@ -5,7 +5,7 @@ include "xlat/defines.i"
3 = WALK, Door_Close (tag, D_SLOW) 3 = WALK, Door_Close (tag, D_SLOW)
4 = WALK|MONST, Door_Raise (tag, D_SLOW, VDOORWAIT) 4 = WALK|MONST, Door_Raise (tag, D_SLOW, VDOORWAIT)
5 = WALK, Floor_RaiseToLowestCeiling (tag, F_SLOW) 5 = WALK, Floor_RaiseToLowestCeiling (tag, F_SLOW)
6 = WALK, Ceiling_CrushAndRaiseA (tag, C_NORMAL, C_NORMAL, 10) 6 = WALK, Ceiling_CrushAndRaiseDist (tag, 8, C_NORMAL, 10)
7 = USE, Stairs_BuildUpDoom (tag, ST_SLOW, 8) 7 = USE, Stairs_BuildUpDoom (tag, ST_SLOW, 8)
8 = WALK, Stairs_BuildUpDoom (tag, ST_SLOW, 8) 8 = WALK, Stairs_BuildUpDoom (tag, ST_SLOW, 8)
9 = USE, Floor_Donut (tag, DORATE, DORATE) 9 = USE, Floor_Donut (tag, DORATE, DORATE)
@ -24,7 +24,7 @@ include "xlat/defines.i"
22 = WALK, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) 22 = WALK, Plat_RaiseAndStayTx0 (tag, P_SLOW/2)
23 = USE, Floor_LowerToLowest (tag, F_SLOW) 23 = USE, Floor_LowerToLowest (tag, F_SLOW)
24 = SHOOT, Floor_RaiseToLowestCeiling (tag, F_SLOW) 24 = SHOOT, Floor_RaiseToLowestCeiling (tag, F_SLOW)
25 = WALK, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) 25 = WALK, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 10)
26 = USE|REP, Door_LockedRaise (0, D_SLOW, VDOORWAIT, BCard | CardIsSkull, tag) 26 = USE|REP, Door_LockedRaise (0, D_SLOW, VDOORWAIT, BCard | CardIsSkull, tag)
27 = USE|REP, Door_LockedRaise (0, D_SLOW, VDOORWAIT, YCard | CardIsSkull, tag) 27 = USE|REP, Door_LockedRaise (0, D_SLOW, VDOORWAIT, YCard | CardIsSkull, tag)
28 = USE|REP, Door_LockedRaise (0, D_SLOW, VDOORWAIT, RCard | CardIsSkull, tag) 28 = USE|REP, Door_LockedRaise (0, D_SLOW, VDOORWAIT, RCard | CardIsSkull, tag)
@ -72,11 +72,11 @@ include "xlat/defines.i"
70 = USE|REP, Floor_LowerToHighest (tag, F_FAST, 136) 70 = USE|REP, Floor_LowerToHighest (tag, F_FAST, 136)
71 = USE, Floor_LowerToHighest (tag, F_FAST, 136) 71 = USE, Floor_LowerToHighest (tag, F_FAST, 136)
72 = WALK|REP, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2) 72 = WALK|REP, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2)
73 = WALK|REP, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) 73 = WALK|REP, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 10)
74 = WALK|REP, Ceiling_CrushStop (tag) 74 = WALK|REP, Ceiling_CrushStop (tag)
75 = WALK|REP, Door_Close (tag, D_SLOW) 75 = WALK|REP, Door_Close (tag, D_SLOW)
76 = WALK|REP, Door_CloseWaitOpen (tag, D_SLOW, 240) 76 = WALK|REP, Door_CloseWaitOpen (tag, D_SLOW, 240)
77 = WALK|REP, Ceiling_CrushAndRaiseA (tag, C_NORMAL, C_NORMAL, 10) 77 = WALK|REP, Ceiling_CrushAndRaiseDist (tag, 8, C_NORMAL, 10)
78 = USE|REP, Floor_TransferNumeric (tag) // <- BOOM special 78 = USE|REP, Floor_TransferNumeric (tag) // <- BOOM special
79 = WALK|REP, Light_ChangeToValue (tag, 35) 79 = WALK|REP, Light_ChangeToValue (tag, 35)
80 = WALK|REP, Light_MaxNeighbor (tag) 80 = WALK|REP, Light_MaxNeighbor (tag)
@ -140,7 +140,7 @@ include "xlat/defines.i"
138 = USE|REP, Light_ChangeToValue (tag, 255) 138 = USE|REP, Light_ChangeToValue (tag, 255)
139 = USE|REP, Light_ChangeToValue (tag, 35) 139 = USE|REP, Light_ChangeToValue (tag, 35)
140 = USE, Floor_RaiseByValueTimes8 (tag, F_SLOW, 64) 140 = USE, Floor_RaiseByValueTimes8 (tag, F_SLOW, 64)
141 = WALK, Ceiling_CrushAndRaiseSilentA (tag, C_SLOW, C_SLOW, 10) 141 = WALK, Ceiling_CrushAndRaiseSilentDist (tag, 8, C_SLOW, 10)
/****** The following are all new to BOOM ******/ /****** The following are all new to BOOM ******/
@ -152,7 +152,7 @@ include "xlat/defines.i"
147 = WALK|REP, Floor_RaiseByValueTimes8 (tag, F_SLOW, 64) 147 = WALK|REP, Floor_RaiseByValueTimes8 (tag, F_SLOW, 64)
148 = WALK|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 3) 148 = WALK|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 3)
149 = WALK|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 4) 149 = WALK|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 4)
150 = WALK|REP, Ceiling_CrushAndRaiseSilentA (tag, C_SLOW, C_SLOW, 10) 150 = WALK|REP, Ceiling_CrushAndRaiseSilentDist (tag, 8, C_SLOW, 10)
151 = WALK|REP, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW) 151 = WALK|REP, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW)
152 = WALK|REP, Ceiling_LowerToFloor (tag, C_SLOW) 152 = WALK|REP, Ceiling_LowerToFloor (tag, C_SLOW)
153 = WALK, Floor_TransferTrigger (tag) 153 = WALK, Floor_TransferTrigger (tag)
@ -166,8 +166,8 @@ include "xlat/defines.i"
161 = USE, Floor_RaiseByValue (tag, F_SLOW, 24) 161 = USE, Floor_RaiseByValue (tag, F_SLOW, 24)
162 = USE, Plat_PerpetualRaiseLip (tag, P_SLOW, PLATWAIT, 0) 162 = USE, Plat_PerpetualRaiseLip (tag, P_SLOW, PLATWAIT, 0)
163 = USE, Plat_Stop (tag) 163 = USE, Plat_Stop (tag)
164 = USE, Ceiling_CrushAndRaiseA (tag, C_NORMAL, C_NORMAL, 10) 164 = USE, Ceiling_CrushAndRaiseDist (tag, 8, C_NORMAL, 10)
165 = USE, Ceiling_CrushAndRaiseSilentA (tag, C_SLOW, C_SLOW, 10) 165 = USE, Ceiling_CrushAndRaiseSilentDist (tag, 8, C_SLOW, 10)
166 = USE, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW, 1998) 166 = USE, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW, 1998)
167 = USE, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2) 167 = USE, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2)
168 = USE, Ceiling_CrushStop (tag) 168 = USE, Ceiling_CrushStop (tag)
@ -185,9 +185,9 @@ include "xlat/defines.i"
180 = USE|REP, Floor_RaiseByValue (tag, F_SLOW, 24) 180 = USE|REP, Floor_RaiseByValue (tag, F_SLOW, 24)
181 = USE|REP, Plat_PerpetualRaiseLip (tag, P_SLOW, PLATWAIT, 0) 181 = USE|REP, Plat_PerpetualRaiseLip (tag, P_SLOW, PLATWAIT, 0)
182 = USE|REP, Plat_Stop (tag) 182 = USE|REP, Plat_Stop (tag)
183 = USE|REP, Ceiling_CrushAndRaiseA (tag, C_NORMAL, C_NORMAL, 10) 183 = USE|REP, Ceiling_CrushAndRaiseDist (tag, 8, C_NORMAL, 10)
184 = USE|REP, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) 184 = USE|REP, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 10)
185 = USE|REP, Ceiling_CrushAndRaiseSilentA (tag, C_SLOW, C_SLOW, 10) 185 = USE|REP, Ceiling_CrushAndRaiseSilentDist (tag, 8, C_SLOW, 10)
186 = USE|REP, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW, 1998) 186 = USE|REP, FloorAndCeiling_LowerRaise (tag, F_SLOW, C_SLOW, 1998)
187 = USE|REP, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2) 187 = USE|REP, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2)
188 = USE|REP, Ceiling_CrushStop (tag) 188 = USE|REP, Ceiling_CrushStop (tag)

View File

@ -90,7 +90,7 @@ RetailOnly = 121
3 = WALK, Door_Close (tag, D_SLOW) 3 = WALK, Door_Close (tag, D_SLOW)
4 = WALK|MONST, Door_Raise (tag, D_SLOW, VDOORWAIT) 4 = WALK|MONST, Door_Raise (tag, D_SLOW, VDOORWAIT)
5 = WALK, Floor_RaiseToLowestCeiling (tag, F_SLOW) 5 = WALK, Floor_RaiseToLowestCeiling (tag, F_SLOW)
6 = WALK, Ceiling_CrushAndRaiseA (tag, C_FAST, C_FAST, 10) 6 = WALK, Ceiling_CrushAndRaiseDist (tag, 8, C_FAST, 10)
8 = WALK, Stairs_BuildUpDoom (tag, ST_SLOW, 8) 8 = WALK, Stairs_BuildUpDoom (tag, ST_SLOW, 8)
10 = WALK|MONST, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) 10 = WALK|MONST, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0)
12 = WALK, Light_MaxNeighbor (tag) 12 = WALK, Light_MaxNeighbor (tag)
@ -99,7 +99,7 @@ RetailOnly = 121
17 = WALK, Light_StrobeDoom (tag, 5, 35) 17 = WALK, Light_StrobeDoom (tag, 5, 35)
19 = WALK, Floor_LowerToHighest (tag, F_SLOW, 128) 19 = WALK, Floor_LowerToHighest (tag, F_SLOW, 128)
22 = WALK, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) 22 = WALK, Plat_RaiseAndStayTx0 (tag, P_SLOW/2)
25 = WALK, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 0) 25 = WALK, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 0)
30 = WALK, Floor_RaiseByTexture (tag, F_SLOW) 30 = WALK, Floor_RaiseByTexture (tag, F_SLOW)
35 = WALK, Light_ChangeToValue (tag, 35) 35 = WALK, Light_ChangeToValue (tag, 35)
36 = WALK, Floor_LowerToHighest (tag, F_FAST, 128) 36 = WALK, Floor_LowerToHighest (tag, F_FAST, 128)
@ -128,7 +128,7 @@ RetailOnly = 121
124 = WALK, Teleport_EndGame () 124 = WALK, Teleport_EndGame ()
125 = MONWALK, Teleport (0, tag) 125 = MONWALK, Teleport (0, tag)
130 = WALK, Floor_RaiseToNearest (tag, F_FAST) 130 = WALK, Floor_RaiseToNearest (tag, F_FAST)
141 = WALK, Ceiling_CrushAndRaiseSilentA (tag, C_SLOW, C_SLOW, 0) 141 = WALK, Ceiling_CrushAndRaiseSilentDist (tag, 8, C_SLOW, 10)
174 = WALK, ACS_ExecuteAlways (0, 0, 174, tag) 174 = WALK, ACS_ExecuteAlways (0, 0, 174, tag)
183 = WALK, ACS_ExecuteAlways (0, 0, 183, tag) 183 = WALK, ACS_ExecuteAlways (0, 0, 183, tag)
178 = WALK, Generic_Stairs (tag, ST_FAST, 16, 0, 0) 178 = WALK, Generic_Stairs (tag, ST_FAST, 16, 0, 0)
@ -146,11 +146,11 @@ RetailOnly = 121
216 = WALK|REP, ACS_ExecuteAlways (0, 0, 216, tag) 216 = WALK|REP, ACS_ExecuteAlways (0, 0, 216, tag)
90 = WALK|REP, Door_Raise (tag, D_SLOW, VDOORWAIT) 90 = WALK|REP, Door_Raise (tag, D_SLOW, VDOORWAIT)
72 = WALK|REP, Ceiling_LowerAndCrushDist (tag, C_SLOW, 10) 72 = WALK|REP, Ceiling_LowerAndCrushDist (tag, C_SLOW, 10)
73 = WALK|REP, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 0) 73 = WALK|REP, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 0)
74 = WALK|REP, Ceiling_CrushStop (tag) 74 = WALK|REP, Ceiling_CrushStop (tag)
75 = WALK|REP, Door_Close (tag, D_SLOW) 75 = WALK|REP, Door_Close (tag, D_SLOW)
76 = WALK|REP, Door_CloseWaitOpen (tag, D_SLOW, 240) 76 = WALK|REP, Door_CloseWaitOpen (tag, D_SLOW, 240)
77 = WALK|REP, Ceiling_CrushAndRaiseA (tag, C_FAST, C_FAST, 10) 77 = WALK|REP, Ceiling_CrushAndRaiseDist (tag, 8, C_FAST, 10)
79 = WALK|REP, Light_ChangeToValue (tag, 35) 79 = WALK|REP, Light_ChangeToValue (tag, 35)
80 = WALK|REP, Light_MaxNeighbor (tag) 80 = WALK|REP, Light_MaxNeighbor (tag)
81 = WALK|REP, Light_ChangeToValue (tag, 255) 81 = WALK|REP, Light_ChangeToValue (tag, 255)

View File

@ -162,8 +162,8 @@ Global
{A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|Win32.Build.0 = Release|Win32 {A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|Win32.Build.0 = Release|Win32
{A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|x64.ActiveCfg = Release|x64 {A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|x64.ActiveCfg = Release|x64
{A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|x64.Build.0 = Release|x64 {A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|x64.Build.0 = Release|x64
{9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.ActiveCfg = Release|Win32 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.ActiveCfg = Debug|Win32
{9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.Build.0 = Release|Win32 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.Build.0 = Debug|Win32
{9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|x64.ActiveCfg = Release|x64 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|x64.ActiveCfg = Release|x64
{9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|x64.Build.0 = Release|x64 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|x64.Build.0 = Release|x64
{9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Release|Win32.ActiveCfg = Release|Win32 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Release|Win32.ActiveCfg = Release|Win32

View File

@ -2309,10 +2309,6 @@
RelativePath=".\src\r_plane.cpp" RelativePath=".\src\r_plane.cpp"
> >
</File> </File>
<File
RelativePath=".\src\r_polymost.cpp"
>
</File>
<File <File
RelativePath=".\src\r_segs.cpp" RelativePath=".\src\r_segs.cpp"
> >
@ -2353,10 +2349,6 @@
RelativePath=".\src\r_plane.h" RelativePath=".\src\r_plane.h"
> >
</File> </File>
<File
RelativePath=".\src\r_polymost.h"
>
</File>
<File <File
RelativePath=".\src\r_segs.h" RelativePath=".\src\r_segs.h"
> >