This commit is contained in:
Rachael Alexanderson 2018-03-10 11:08:56 -05:00
commit 50cd3fbef5
46 changed files with 426 additions and 266 deletions

View file

@ -32,7 +32,7 @@ environment:
build_script:
- md build
- cd build
- cmake -G "%GENERATOR%" -T "%TOOLSET%" ..
- cmake -G "%GENERATOR%" -T "%TOOLSET%" -DPK3_QUIET_ZIPDIR=YES ..
- cmake --build . --config "%CONFIGURATION%" -- /verbosity:minimal
after_build:

View file

@ -70,15 +70,15 @@ matrix:
- os: linux
compiler: clang
env:
- CLANG_VERSION=5.0
- CLANG_VERSION=6.0
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=MinSizeRel -DDYN_OPENAL=NO -DDYN_SNDFILE=NO -DDYN_MPG123=NO -DDYN_FLUIDSYNTH=NO"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- llvm-toolchain-trusty-6.0
packages:
- clang-5.0
- clang-6.0
- libstdc++-5-dev
- libsdl2-dev
- libgme-dev
@ -98,7 +98,7 @@ script:
- echo ${TRAVIS_BUILD_DIR}
- mkdir build
- cd build
- cmake ${CMAKE_OPTIONS} ..
- cmake ${CMAKE_OPTIONS} -DPK3_QUIET_ZIPDIR=YES ..
- make -j2
notifications:

View file

@ -55,23 +55,24 @@ function( assort_pk3_source_folder FOLDER_NAME PK3_DIR )
endforeach()
endfunction()
option( PK3_QUIET_ZIPDIR "Do not list files processed by zipdir" NO )
if( PK3_QUIET_ZIPDIR )
set( PK3_ZIPDIR_OPTIONS "-q" )
endif()
# Simplify pk3 building, add_pk3(filename srcdirectory)
function( add_pk3 PK3_NAME PK3_DIR )
# message(STATUS "Creating build rule for PK3 ${PK3_NAME} ${PK3_DIR}")
# Generate target name. Just use "pk3" for main pk3 target.
string( REPLACE "." "_" PK3_TARGET ${PK3_NAME} )
if( ${PK3_TARGET} STREQUAL "zdoom_pk3" )
set( PK3_TARGET "pk3" )
endif()
if( NOT ZDOOM_OUTPUT_OLDSTYLE )
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
COMMAND zipdir -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
COMMAND zipdir -udf ${PK3_ZIPDIR_OPTIONS} ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $<TARGET_FILE_DIR:zdoom>/${PK3_NAME}
DEPENDS zipdir )
else()
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
COMMAND zipdir -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
COMMAND zipdir -udf ${PK3_ZIPDIR_OPTIONS} ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
DEPENDS zipdir )
endif()
# Create a list of source files for this PK3, for use in the IDE

View file

@ -403,6 +403,16 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
endif()
endif()
# Check for thread_local keyword, it's optional at the moment
CHECK_CXX_SOURCE_COMPILES("thread_local int i; int main() { i = 0; }"
HAVE_THREAD_LOCAL)
if( NOT HAVE_THREAD_LOCAL )
message( WARNING "C++ compiler doesn't support thread_local storage duration specifier" )
add_definitions( -Dthread_local= )
endif()
# Check for functions that may or may not exist.
CHECK_FUNCTION_EXISTS( filelength FILELENGTH_EXISTS )

View file

@ -138,6 +138,7 @@ CVAR (Color, am_lockedcolor, 0x007800, CVAR_ARCHIVE);
CVAR (Color, am_intralevelcolor, 0x0000ff, CVAR_ARCHIVE);
CVAR (Color, am_interlevelcolor, 0xff0000, CVAR_ARCHIVE);
CVAR (Color, am_secretsectorcolor, 0xff00ff, CVAR_ARCHIVE);
CVAR (Color, am_unexploredsecretcolor, 0xff00ff, CVAR_ARCHIVE);
CVAR (Color, am_thingcolor_friend, 0xfcfcfc, CVAR_ARCHIVE);
CVAR (Color, am_thingcolor_monster, 0xfcfcfc, CVAR_ARCHIVE);
CVAR (Color, am_thingcolor_ncmonster, 0xfcfcfc, CVAR_ARCHIVE);
@ -158,6 +159,7 @@ CVAR (Color, am_ovunseencolor, 0x00226e, CVAR_ARCHIVE);
CVAR (Color, am_ovtelecolor, 0xffff00, CVAR_ARCHIVE);
CVAR (Color, am_ovinterlevelcolor, 0xffff00, CVAR_ARCHIVE);
CVAR (Color, am_ovsecretsectorcolor,0x00ffff, CVAR_ARCHIVE);
CVAR (Color, am_ovunexploredsecretcolor,0x00ffff, CVAR_ARCHIVE);
CVAR (Color, am_ovthingcolor, 0xe88800, CVAR_ARCHIVE);
CVAR (Color, am_ovthingcolor_friend, 0xe88800, CVAR_ARCHIVE);
CVAR (Color, am_ovthingcolor_monster, 0xe88800, CVAR_ARCHIVE);
@ -230,6 +232,7 @@ static const char *ColorNames[] = {
"IntraTeleportColor",
"InterTeleportColor",
"SecretSectorColor",
"UnexploredSecretColor",
"PortalColor",
"AlmostBackgroundColor",
NULL
@ -261,6 +264,7 @@ struct AMColorset
IntraTeleportColor,
InterTeleportColor,
SecretSectorColor,
UnexploredSecretColor,
PortalColor,
AlmostBackgroundColor,
AM_NUM_COLORS
@ -362,6 +366,7 @@ static FColorCVar *cv_standard[] = {
&am_intralevelcolor,
&am_interlevelcolor,
&am_secretsectorcolor,
&am_unexploredsecretcolor,
&am_portalcolor
};
@ -388,6 +393,7 @@ static FColorCVar *cv_overlay[] = {
&am_ovtelecolor,
&am_ovinterlevelcolor,
&am_ovsecretsectorcolor,
&am_ovunexploredsecretcolor,
&am_ovportalcolor
};
@ -430,6 +436,7 @@ static unsigned char DoomColors[]= {
NOT_USED, // intrateleport
NOT_USED, // interteleport
NOT_USED, // secretsector
NOT_USED, // unexploredsecretsector
0x10,0x10,0x10, // almostbackground
0x40,0x40,0x40 // portal
};
@ -457,6 +464,7 @@ static unsigned char StrifeColors[]= {
NOT_USED, // intrateleport
NOT_USED, // interteleport
NOT_USED, // secretsector
NOT_USED, // unexploredsecretsector
0x10,0x10,0x10, // almostbackground
0x40,0x40,0x40 // portal
};
@ -484,6 +492,7 @@ static unsigned char RavenColors[]= {
NOT_USED, // intrateleport
NOT_USED, // interteleport
NOT_USED, // secretsector
NOT_USED, // unexploredsecretsector
0x10,0x10,0x10, // almostbackground
0x50,0x50,0x50 // portal
};
@ -2209,7 +2218,7 @@ void AM_drawSubsectors()
//
//=============================================================================
static bool AM_CheckSecret(line_t *line)
static int AM_CheckSecret(line_t *line)
{
if (AMColors.isValid(AMColors.SecretSectorColor))
{
@ -2217,20 +2226,20 @@ static bool AM_CheckSecret(line_t *line)
{
if (line->frontsector->wasSecret())
{
if (am_map_secrets!=0 && !line->frontsector->isSecret()) return true;
if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true;
if (am_map_secrets!=0 && !line->frontsector->isSecret()) return 1;
if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return 2;
}
}
if (line->backsector != NULL)
{
if (line->backsector->wasSecret())
{
if (am_map_secrets!=0 && !line->backsector->isSecret()) return true;
if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true;
if (am_map_secrets!=0 && !line->backsector->isSecret()) return 1;
if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return 2;
}
}
}
return false;
return 0;
}
@ -2584,11 +2593,15 @@ void AM_drawWalls (bool allmap)
{
AM_drawMline(&l, AMColors.PortalColor);
}
else if (AM_CheckSecret(&line))
else if (AM_CheckSecret(&line) == 1)
{
// map secret sectors like Boom
AM_drawMline(&l, AMColors.SecretSectorColor);
}
else if (AM_CheckSecret(&line) == 2)
{
AM_drawMline(&l, AMColors.UnexploredSecretColor);
}
else if (line.flags & ML_SECRET)
{ // secret door
if (am_cheat != 0 && line.backsector != NULL)

View file

@ -41,6 +41,8 @@
#include "serializer.h"
#include "d_player.h"
#include "vm.h"
#include "c_dispatch.h"
#include "v_text.h"
static int ThinkCount;
@ -462,7 +464,57 @@ void DThinker::DestroyThinkersInList (FThinkerList &list)
//
//
//==========================================================================
CVAR(Bool, profilethinkers, false, 0)
static unsigned int profilethinkers, profilelimit;
CCMD(profilethinkers)
{
const int argc = argv.argc();
if (argc == 2 || argc == 3)
{
const char *str = argv[1];
bool ascend = true;
if (*str == '+')
{
++str;
}
else if (*str == '-')
{
ascend = false;
++str;
}
int mode = 0;
switch (*str)
{
case 't': mode = ascend ? 7 : 8; break;
case 'a': mode = ascend ? 5 : 6; break;
case '#': mode = ascend ? 3 : 4; break;
case 'c': mode = ascend ? 1 : 2; break;
default: mode = atoi(str); break;
}
profilethinkers = mode;
profilelimit = argc == 3 ? atoi(argv[2]) : 0;
}
else
{
Printf(
"Usage: profilethinkers [+|-][t|a|#|c] [limit]\n"
" profilethinkers [1..8] [limit]\n\n"
"Sorting modes:\n"
TEXTCOLOR_YELLOW "c +c 1 " TEXTCOLOR_NORMAL "actor class, ascending\n"
TEXTCOLOR_YELLOW " -c 2 " TEXTCOLOR_NORMAL "actor class, descending\n"
TEXTCOLOR_YELLOW "# +# 3 " TEXTCOLOR_NORMAL "number of calls, ascending\n"
TEXTCOLOR_YELLOW " -# 4 " TEXTCOLOR_NORMAL "number of calls, descending\n"
TEXTCOLOR_YELLOW "a +a 5 " TEXTCOLOR_NORMAL "average time, ascending\n"
TEXTCOLOR_YELLOW " -a 6 " TEXTCOLOR_NORMAL "average time, descending\n"
TEXTCOLOR_YELLOW "t +t 7 " TEXTCOLOR_NORMAL "total time, ascending\n"
TEXTCOLOR_YELLOW " -t 8 " TEXTCOLOR_NORMAL "total time, descending\n");
}
}
struct ProfileInfo
{
@ -526,13 +578,63 @@ void DThinker::RunThinkers ()
count += ProfileThinkers(&FreshThinkers[i], &Thinkers[i]);
}
} while (count != 0);
struct SortedProfileInfo
{
const char* className;
int numcalls;
double time;
};
TArray<SortedProfileInfo> sorted;
sorted.Grow(Profiles.CountUsed());
auto it = TMap<FName, ProfileInfo>::Iterator(Profiles);
TMap<FName, ProfileInfo>::Pair *pair;
while (it.NextPair(pair))
{
Printf("%s, %dx, %fms\n", pair->Key.GetChars(), pair->Value.numcalls, pair->Value.timer.TimeMS());
sorted.Push({ pair->Key.GetChars(), pair->Value.numcalls, pair->Value.timer.TimeMS() });
}
profilethinkers = false;
std::sort(sorted.begin(), sorted.end(), [](const SortedProfileInfo& left, const SortedProfileInfo& right)
{
switch (profilethinkers)
{
case 1: // by name, from A to Z
return stricmp(left.className, right.className) < 0;
case 2: // by name, from Z to A
return stricmp(right.className, left.className) < 0;
case 3: // number of calls, ascending
return left.numcalls < right.numcalls;
case 4: // number of calls, descending
return right.numcalls < left.numcalls;
case 5: // average time, ascending
return left.time / left.numcalls < right.time / right.numcalls;
case 6: // average time, descending
return right.time / right.numcalls < left.time / left.numcalls;
case 7: // total time, ascending
return left.time < right.time;
default: // total time, descending
return right.time < left.time;
}
});
Printf(TEXTCOLOR_YELLOW "Total, ms Averg, ms Calls Actor class\n");
Printf(TEXTCOLOR_YELLOW "---------- ---------- ------ --------------------\n");
const unsigned count = MIN(profilelimit > 0 ? profilelimit : UINT_MAX, sorted.Size());
for (unsigned i = 0; i < count; ++i)
{
const SortedProfileInfo& info = sorted[i];
Printf("%s%10.6f %s%10.6f %s%6d %s%s\n",
profilethinkers >= 7 ? TEXTCOLOR_YELLOW : TEXTCOLOR_WHITE, info.time,
profilethinkers == 5 || profilethinkers == 6 ? TEXTCOLOR_YELLOW : TEXTCOLOR_WHITE, info.time / info.numcalls,
profilethinkers == 3 || profilethinkers == 4 ? TEXTCOLOR_YELLOW : TEXTCOLOR_WHITE, info.numcalls,
profilethinkers == 1 || profilethinkers == 2 ? TEXTCOLOR_YELLOW : TEXTCOLOR_WHITE, info.className);
}
profilethinkers = 0;
}
ThinkCycles.Unclock();

View file

@ -701,8 +701,8 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, AttachMessage)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_OBJECT(msg, DHUDMessageBase);
PARAM_UINT(id);
PARAM_INT(layer);
PARAM_UINT_DEF(id);
PARAM_INT_DEF(layer);
self->AttachMessage(msg, id, layer);
return 0;
}

View file

@ -180,6 +180,11 @@ static void RemapVoxelSlabs(kvxslab_t *dest, int size, const uint8_t *remap)
//
//==========================================================================
#if defined __GNUC__ && !defined __clang__
#pragma GCC push_options
#pragma GCC optimize ("-fno-tree-loop-vectorize")
#endif // __GNUC__ && !__clang__
FVoxel *R_LoadKVX(int lumpnum)
{
const kvxslab_t *slabs[MAXVOXMIPS];
@ -320,6 +325,10 @@ FVoxel *R_LoadKVX(int lumpnum)
return voxel;
}
#if defined __GNUC__ && !defined __clang__
#pragma GCC pop_options
#endif // __GNUC__ && !__clang__
//==========================================================================
//
//

View file

@ -924,11 +924,11 @@ void FxBoolCast::EmitCompare(VMFunctionBuilder *build, bool invert, TArray<size_
//
//==========================================================================
FxIntCast::FxIntCast(FxExpression *x, bool nowarn, bool explicitly)
FxIntCast::FxIntCast(FxExpression *x, bool nowarn, bool explicitly, bool isunsigned)
: FxExpression(EFX_IntCast, x->ScriptPosition)
{
basex=x;
ValueType = TypeSInt32;
ValueType = isunsigned ? TypeUInt32 : TypeSInt32;
NoWarn = nowarn;
Explicit = explicitly;
}
@ -1632,7 +1632,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
else if (ValueType->isInt())
{
// This is only for casting to actual ints. Subtypes representing an int will be handled elsewhere.
FxExpression *x = new FxIntCast(basex, NoWarn, Explicit);
FxExpression *x = new FxIntCast(basex, NoWarn, Explicit, static_cast<PInt*>(ValueType)->Unsigned);
x = x->Resolve(ctx);
basex = nullptr;
delete this;

View file

@ -604,7 +604,7 @@ class FxIntCast : public FxExpression
public:
FxIntCast(FxExpression *x, bool nowarn, bool explicitly = false);
FxIntCast(FxExpression *x, bool nowarn, bool explicitly = false, bool isunsigned = false);
~FxIntCast();
FxExpression *Resolve(FCompileContext&);

View file

@ -411,6 +411,7 @@ bool AssertObject(void * ob);
#define PARAM_EXISTS(p) ((p) < numparam)
#define PARAM_INT_DEF_AT(p,x) int x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = param[p].i; } else { ASSERTINT(defaultparam[p]); x = defaultparam[p].i; }
#define PARAM_UINT_DEF_AT(p,x) unsigned x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = param[p].i; } else { ASSERTINT(defaultparam[p]); x = defaultparam[p].i; }
#define PARAM_BOOL_DEF_AT(p,x) bool x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = !!param[p].i; } else { ASSERTINT(defaultparam[p]); x = !!defaultparam[p].i; }
#define PARAM_NAME_DEF_AT(p,x) FName x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = ENamedName(param[p].i); } else { ASSERTINT(defaultparam[p]); x = ENamedName(defaultparam[p].i); }
#define PARAM_SOUND_DEF_AT(p,x) FSoundID x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = FSoundID(param[p].i); } else { ASSERTINT(defaultparam[p]); x = FSoundID(defaultparam[p].i); }
@ -449,6 +450,7 @@ bool AssertObject(void * ob);
#define PARAM_CLASS_NOT_NULL(x,base) ++paramnum; PARAM_CLASS_NOT_NULL_AT(paramnum,x,base)
#define PARAM_INT_DEF(x) ++paramnum; PARAM_INT_DEF_AT(paramnum,x)
#define PARAM_UINT_DEF(x) ++paramnum; PARAM_UINT_DEF_AT(paramnum,x)
#define PARAM_BOOL_DEF(x) ++paramnum; PARAM_BOOL_DEF_AT(paramnum,x)
#define PARAM_NAME_DEF(x) ++paramnum; PARAM_NAME_DEF_AT(paramnum,x)
#define PARAM_SOUND_DEF(x) ++paramnum; PARAM_SOUND_DEF_AT(paramnum,x)

View file

@ -198,7 +198,7 @@ protected:
class MIDIWaveWriter : public SoftSynthMIDIDevice
{
public:
MIDIWaveWriter(const char *filename, MIDIDevice *devtouse);
MIDIWaveWriter(const char *filename, SoftSynthMIDIDevice *devtouse);
~MIDIWaveWriter();
int Resume();
int Open(MidiCallback cb, void *userdata)

View file

@ -87,11 +87,11 @@ struct FmtChunk
//
//==========================================================================
MIDIWaveWriter::MIDIWaveWriter(const char *filename, MIDIDevice *playdevice)
: SoftSynthMIDIDevice(playDevice->GetSampleRate())
MIDIWaveWriter::MIDIWaveWriter(const char *filename, SoftSynthMIDIDevice *playdevice)
: SoftSynthMIDIDevice(playdevice->GetSampleRate())
{
File = FileWriter::Open(filename);
playDevice = (SoftSynthMIDIDevice*) playdevice;
playDevice = playdevice;
if (File != nullptr)
{ // Write wave header
uint32_t work[3];

View file

@ -319,8 +319,13 @@ bool MIDIStreamer::DumpWave(const char *filename, int subsong, int samplerate)
assert(MIDI == NULL);
auto devtype = SelectMIDIDevice(DeviceType);
if (devtype == MDEV_MMAPI)
{
Printf("MMAPI device is not supported");
return false;
}
MIDI = CreateMIDIDevice(devtype, samplerate);
MIDI = new MIDIWaveWriter(filename, MIDI);
MIDI = new MIDIWaveWriter(filename, reinterpret_cast<SoftSynthMIDIDevice *>(MIDI));
return InitPlayback();
}

View file

@ -65,13 +65,14 @@ namespace swrenderer
Thread = thread;
}
void FarClipLine::Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane)
void FarClipLine::Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, Fake3DOpaque opaque3dfloor)
{
mSubsector = subsector;
mFrontSector = mSubsector->sector;
mLineSegment = line;
mFloorPlane = linefloorplane;
mCeilingPlane = lineceilingplane;
m3DFloor = opaque3dfloor;
DVector2 pt1 = line->v1->fPos() - Thread->Viewport->viewpoint.Pos;
DVector2 pt2 = line->v2->fPos() - Thread->Viewport->viewpoint.Pos;
@ -153,7 +154,7 @@ namespace swrenderer
for (int x = x1; x < x2; ++x)
{
short top = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKECEILING) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x];
short top = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeCeiling) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x];
short bottom = MIN(walltop.ScreenY[x], floorclip[x]);
if (top < bottom)
{
@ -177,7 +178,7 @@ namespace swrenderer
for (int x = x1; x < x2; ++x)
{
short top = MAX(wallbottom.ScreenY[x], ceilingclip[x]);
short bottom = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKEFLOOR) ? clip3d->fakeFloor->floorclip[x] : floorclip[x];
short bottom = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeFloor) ? clip3d->fakeFloor->floorclip[x] : floorclip[x];
if (top < bottom)
{
assert(bottom <= viewheight);

View file

@ -28,7 +28,7 @@ namespace swrenderer
{
public:
FarClipLine(RenderThread *thread);
void Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane);
void Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, Fake3DOpaque opaque3dfloor);
RenderThread *Thread = nullptr;
@ -44,6 +44,7 @@ namespace swrenderer
seg_t *mLineSegment;
VisiblePlane *mFloorPlane;
VisiblePlane *mCeilingPlane;
Fake3DOpaque m3DFloor;
double mFrontCeilingZ1;
double mFrontCeilingZ2;

View file

@ -54,7 +54,7 @@
namespace swrenderer
{
void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap)
void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap)
{
// This is essentially the same as R_MapVisPlane but with an extra step
// to create new horizontal spans whenever the light changes enough that

View file

@ -31,7 +31,7 @@ namespace swrenderer
class RenderFogBoundary
{
public:
void Render(RenderThread *thread, int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap);
void Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap);
private:
void RenderSection(RenderThread *thread, int y, int y2, int x1);

View file

@ -71,7 +71,7 @@ namespace swrenderer
Thread = thread;
}
void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, bool infog, FDynamicColormap *colormap)
void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, bool infog, FDynamicColormap *colormap, Fake3DOpaque opaque3dfloor)
{
mSubsector = subsector;
mFrontSector = sector;
@ -81,6 +81,7 @@ namespace swrenderer
foggy = infog;
basecolormap = colormap;
mLineSegment = line;
m3DFloor = opaque3dfloor;
DVector2 pt1 = line->v1->fPos() - Thread->Viewport->viewpoint.Pos;
DVector2 pt2 = line->v2->fPos() - Thread->Viewport->viewpoint.Pos;
@ -133,7 +134,7 @@ namespace swrenderer
Clip3DFloors *clip3d = Thread->Clip3D.get();
if (!(clip3d->fake3D & FAKE3D_FAKEBACK))
if (m3DFloor.type != Fake3DOpaque::FakeBack)
{
mBackSector = line->backsector;
}
@ -141,7 +142,7 @@ namespace swrenderer
if (mBackSector)
{
// kg3D - its fake, no transfer_heights
if (!(clip3d->fake3D & FAKE3D_FAKEBACK))
if (m3DFloor.type != Fake3DOpaque::FakeBack)
{ // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
mBackSector = Thread->OpaquePass->FakeFlat(mBackSector, &tempsec, nullptr, nullptr, mLineSegment, WallC.sx1, WallC.sx2, mFrontCeilingZ1, mFrontCeilingZ2);
}
@ -151,15 +152,15 @@ namespace swrenderer
mBackCeilingZ2 = mBackSector->ceilingplane.ZatPoint(line->v2);
mBackFloorZ2 = mBackSector->floorplane.ZatPoint(line->v2);
if (clip3d->fake3D & FAKE3D_FAKEBACK)
if (m3DFloor.type == Fake3DOpaque::FakeBack)
{
if (mFrontFloorZ1 >= mBackFloorZ1 && mFrontFloorZ2 >= mBackFloorZ2)
{
clip3d->fake3D |= FAKE3D_CLIPBOTFRONT;
m3DFloor.clipBotFront = true;
}
if (mFrontCeilingZ1 <= mBackCeilingZ1 && mFrontCeilingZ2 <= mBackCeilingZ2)
{
clip3d->fake3D |= FAKE3D_CLIPTOPFRONT;
m3DFloor.clipTopFront = true;
}
}
}
@ -325,7 +326,7 @@ namespace swrenderer
// 3D floors code abuses the line render code to update plane clipping
// lists but doesn't actually draw anything.
bool onlyUpdatePlaneClip = (clip3d->fake3D & FAKE3D_FAKEMASK) ? true : false;
bool onlyUpdatePlaneClip = (m3DFloor.type != Fake3DOpaque::Normal);
if (!onlyUpdatePlaneClip)
Thread->DrawSegments->Push(draw_segment);
@ -516,9 +517,9 @@ namespace swrenderer
MarkFloorPlane(start, stop);
Mark3DFloors(start, stop);
if (clip3d->fake3D & FAKE3D_FAKEMASK)
if (m3DFloor.type != Fake3DOpaque::Normal)
{
return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0;
return false;
}
MarkOpaquePassClip(start, stop);
@ -557,7 +558,7 @@ namespace swrenderer
Thread->Portal->AddLinePortal(mLineSegment->linedef, draw_segment->x1, draw_segment->x2, draw_segment->sprtopclip, draw_segment->sprbottomclip);
}
return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0;
return m3DFloor.type == Fake3DOpaque::Normal;
}
bool SWRenderLine::ShouldMarkFloor() const
@ -1015,7 +1016,7 @@ namespace swrenderer
for (int x = x1; x < x2; ++x)
{
short top = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKECEILING) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x];
short top = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeCeiling) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x];
short bottom = MIN(walltop.ScreenY[x], floorclip[x]);
if (top < bottom)
{
@ -1039,7 +1040,7 @@ namespace swrenderer
for (int x = x1; x < x2; ++x)
{
short top = MAX(wallbottom.ScreenY[x], ceilingclip[x]);
short bottom = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKEFLOOR) ? clip3d->fakeFloor->floorclip[x] : floorclip[x];
short bottom = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeFloor) ? clip3d->fakeFloor->floorclip[x] : floorclip[x];
if (top < bottom)
{
assert(bottom <= viewheight);
@ -1055,12 +1056,12 @@ namespace swrenderer
Clip3DFloors *clip3d = Thread->Clip3D.get();
// kg3D - fake planes clipping
if (clip3d->fake3D & FAKE3D_REFRESHCLIP)
if (m3DFloor.type == Fake3DOpaque::FakeBack)
{
auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = Thread->OpaquePass->floorclip;
if (clip3d->fake3D & FAKE3D_CLIPBOTFRONT)
if (m3DFloor.clipBotFront)
{
memcpy(clip3d->fakeFloor->floorclip + x1, wallbottom.ScreenY + x1, (x2 - x1) * sizeof(short));
}
@ -1072,7 +1073,7 @@ namespace swrenderer
}
memcpy(clip3d->fakeFloor->floorclip + x1, walllower.ScreenY + x1, (x2 - x1) * sizeof(short));
}
if (clip3d->fake3D & FAKE3D_CLIPTOPFRONT)
if (m3DFloor.clipTopFront)
{
memcpy(clip3d->fakeFloor->ceilingclip + x1, walltop.ScreenY + x1, (x2 - x1) * sizeof(short));
}

View file

@ -25,6 +25,7 @@
#include "vectors.h"
#include "r_wallsetup.h"
#include "swrenderer/segments/r_clipsegment.h"
#include "swrenderer/scene/r_3dfloors.h"
struct seg_t;
struct subsector_t;
@ -71,7 +72,7 @@ namespace swrenderer
{
public:
SWRenderLine(RenderThread *thread);
void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap);
void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque fake3DOpaque);
RenderThread *Thread = nullptr;
@ -109,6 +110,7 @@ namespace swrenderer
VisiblePlane *mFloorPlane;
VisiblePlane *mCeilingPlane;
seg_t *mLineSegment;
Fake3DOpaque m3DFloor;
double mBackCeilingZ1;
double mBackCeilingZ2;

View file

@ -63,11 +63,12 @@ namespace swrenderer
Thread = thread;
}
void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2)
void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2, Fake3DTranslucent clip3DFloor)
{
auto viewport = Thread->Viewport.get();
curline = ds->curline;
m3DFloor = clip3DFloor;
float alpha = (float)MIN(curline->linedef->alpha, 1.);
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
@ -102,17 +103,13 @@ namespace swrenderer
Clip3DFloors *clip3d = Thread->Clip3D.get();
if (!(clip3d->fake3D & FAKE3D_CLIPTOP))
{
clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos);
}
CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedLightLevel() < 0)
{
double clipTop = m3DFloor.clipTop ? m3DFloor.sclipTop : sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos);
for (int i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
{
if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0())
if (clipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0())
{
lightlist_t *lit = &frontsector->e->XFloor.lightlist[i];
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
@ -123,15 +120,13 @@ namespace swrenderer
}
}
bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX);
// [RH] Draw fog partition
bool renderwall = true;
bool notrelevant = false;
if (ds->bFogBoundary)
{
short *mfloorclip = ds->sprbottomclip - ds->x1;
short *mceilingclip = ds->sprtopclip - ds->x1;
const short *mfloorclip = ds->sprbottomclip - ds->x1;
const short *mceilingclip = ds->sprtopclip - ds->x1;
RenderFogBoundary renderfog;
renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, wallshade, rw_light, rw_lightstep, basecolormap);
@ -145,7 +140,7 @@ namespace swrenderer
}
if (renderwall)
notrelevant = RenderWall(ds, x1, x2, walldrawerargs, columndrawerargs, visible, basecolormap, wallshade, wrap);
notrelevant = RenderWall(ds, x1, x2, walldrawerargs, columndrawerargs, visible, basecolormap, wallshade);
if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls())
{
@ -153,22 +148,12 @@ namespace swrenderer
}
if (!notrelevant)
{
if (clip3d->fake3D & FAKE3D_REFRESHCLIP)
{
if (!wrap)
{
assert(ds->bkup != nullptr);
memcpy(ds->sprtopclip, ds->bkup, (ds->x2 - ds->x1) * 2);
}
}
else
{
fillshort(ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
}
ds->sprclipped = true;
fillshort(ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
}
}
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade, bool wrap)
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade)
{
auto viewport = Thread->Viewport.get();
Clip3DFloors *clip3d = Thread->Clip3D.get();
@ -179,8 +164,8 @@ namespace swrenderer
tex = tex->GetRawTexture();
}
short *mfloorclip = ds->sprbottomclip - ds->x1;
short *mceilingclip = ds->sprtopclip - ds->x1;
const short *mfloorclip = ds->sprbottomclip - ds->x1;
const short *mceilingclip = ds->sprtopclip - ds->x1;
float *MaskedSWall = ds->swall - ds->x1;
float MaskedScaleY = ds->yscale;
@ -220,6 +205,7 @@ namespace swrenderer
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX);
if (!wrap)
{ // Texture does not wrap vertically.
double textop;
@ -263,11 +249,11 @@ namespace swrenderer
return false;
}
if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && textop < clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z)
if (m3DFloor.clipBottom && textop < m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z)
{
return true;
}
if ((clip3d->fake3D & FAKE3D_CLIPTOP) && textop - texheight > clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z)
if (m3DFloor.clipTop && textop - texheight > m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z)
{
return true;
}
@ -277,21 +263,26 @@ namespace swrenderer
WallC.sx1 = ds->sx1;
WallC.sx2 = ds->sx2;
if (clip3d->fake3D & FAKE3D_CLIPTOP)
double top, bot;
GetMaskedWallTopBottom(ds, top, bot);
top -= Thread->Viewport->viewpoint.Pos.Z;
bot -= Thread->Viewport->viewpoint.Pos.Z;
if (m3DFloor.clipTop)
{
wallupper.Project(Thread->Viewport.get(), textop < clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z ? textop : clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
wallupper.Project(Thread->Viewport.get(), textop < m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z ? textop : m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
}
else
{
wallupper.Project(Thread->Viewport.get(), textop, &WallC);
wallupper.Project(Thread->Viewport.get(), MIN(textop, top), &WallC);
}
if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
if (m3DFloor.clipBottom)
{
walllower.Project(Thread->Viewport.get(), textop - texheight > clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z ? textop - texheight : clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
walllower.Project(Thread->Viewport.get(), textop - texheight > m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z ? textop - texheight : m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
}
else
{
walllower.Project(Thread->Viewport.get(), textop - texheight, &WallC);
walllower.Project(Thread->Viewport.get(), MAX(textop - texheight, bot), &WallC);
}
for (int i = x1; i < x2; i++)
@ -377,9 +368,9 @@ namespace swrenderer
}
}
if (clip3d->fake3D & FAKE3D_CLIPTOP)
if (m3DFloor.clipTop)
{
wallupper.Project(Thread->Viewport.get(), clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
for (int i = x1; i < x2; i++)
{
if (wallupper.ScreenY[i] < mceilingclip[i])
@ -387,9 +378,9 @@ namespace swrenderer
}
mceilingclip = wallupper.ScreenY;
}
if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
if (m3DFloor.clipBottom)
{
walllower.Project(Thread->Viewport.get(), clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
for (int i = x1; i < x2; i++)
{
if (walllower.ScreenY[i] > mfloorclip[i])
@ -412,7 +403,7 @@ namespace swrenderer
}
// kg3D - render one fake wall
void RenderDrawSegment::RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap)
void RenderDrawSegment::RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap, double clipTop, double clipBottom)
{
int i;
double xscale;
@ -428,8 +419,8 @@ namespace swrenderer
rw_lightstep = ds->lightstep;
rw_light = ds->light + (x1 - ds->x1) * rw_lightstep;
short *mfloorclip = ds->sprbottomclip - ds->x1;
short *mceilingclip = ds->sprtopclip - ds->x1;
const short *mfloorclip = ds->sprbottomclip - ds->x1;
const short *mceilingclip = ds->sprtopclip - ds->x1;
//double spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
float *MaskedSWall = ds->swall - ds->x1;
@ -495,8 +486,8 @@ namespace swrenderer
WallT = ds->tmapvals;
Clip3DFloors *clip3d = Thread->Clip3D.get();
wallupper.Project(Thread->Viewport.get(), clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
walllower.Project(Thread->Viewport.get(), clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
walllower.Project(Thread->Viewport.get(), clipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
for (i = x1; i < x2; i++)
{
@ -552,15 +543,14 @@ namespace swrenderer
Clip3DFloors *clip3d = Thread->Clip3D.get();
// maybe fix clipheights
if (!(clip3d->fake3D & FAKE3D_CLIPBOTTOM)) clip3d->sclipBottom = floorHeight;
if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) clip3d->sclipTop = ceilingHeight;
double clipTop = m3DFloor.clipTop ? m3DFloor.sclipTop : ceilingHeight;
double clipBottom = m3DFloor.clipBottom ? m3DFloor.sclipBottom : floorHeight;
// maybe not visible
if (clip3d->sclipBottom >= frontsector->CenterCeiling()) return;
if (clip3d->sclipTop <= frontsector->CenterFloor()) return;
if (clipBottom >= frontsector->CenterCeiling()) return;
if (clipTop <= frontsector->CenterFloor()) return;
if (clip3d->fake3D & FAKE3D_DOWN2UP)
if (m3DFloor.down2Up)
{ // bottom to viewz
last = 0;
for (i = backsector->e->XFloor.ffloors.Size() - 1; i >= 0; i--)
@ -571,7 +561,7 @@ namespace swrenderer
// visible?
passed = 0;
if (!(rover->flags & FF_RENDERSIDES) || rover->top.plane->isSlope() || rover->bottom.plane->isSlope() ||
rover->top.plane->Zat0() <= clip3d->sclipBottom ||
rover->top.plane->Zat0() <= clipBottom ||
rover->bottom.plane->Zat0() >= ceilingHeight ||
rover->top.plane->Zat0() <= floorHeight)
{
@ -586,7 +576,7 @@ namespace swrenderer
}
rw_pic = nullptr;
if (rover->bottom.plane->Zat0() >= clip3d->sclipTop || passed)
if (rover->bottom.plane->Zat0() >= clipTop || passed)
{
if (last)
{
@ -608,8 +598,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible?
if (fover->top.plane->Zat0() <= clip3d->sclipBottom) continue; // no
if (fover->bottom.plane->Zat0() >= clip3d->sclipTop)
if (fover->top.plane->Zat0() <= clipBottom) continue; // no
if (fover->bottom.plane->Zat0() >= clipTop)
{ // no, last possible
fover = nullptr;
break;
@ -661,8 +651,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible?
if (fover->top.plane->Zat0() <= clip3d->sclipBottom) continue; // no
if (fover->bottom.plane->Zat0() >= clip3d->sclipTop)
if (fover->top.plane->Zat0() <= clipBottom) continue; // no
if (fover->bottom.plane->Zat0() >= clipTop)
{ // visible, last possible
fover = nullptr;
break;
@ -713,7 +703,7 @@ namespace swrenderer
{
for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{
if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0())
if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0())
{
lightlist_t *lit = &backsector->e->XFloor.lightlist[j];
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
@ -727,7 +717,7 @@ namespace swrenderer
{
for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{
if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0())
if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0())
{
lightlist_t *lit = &frontsector->e->XFloor.lightlist[j];
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
@ -742,7 +732,7 @@ namespace swrenderer
if (rw_pic != DONT_DRAW)
{
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap, clipTop, clipBottom);
}
else rw_pic = nullptr;
break;
@ -759,7 +749,7 @@ namespace swrenderer
passed = 0;
if (!(rover->flags & FF_RENDERSIDES) ||
rover->top.plane->isSlope() || rover->bottom.plane->isSlope() ||
rover->bottom.plane->Zat0() >= clip3d->sclipTop ||
rover->bottom.plane->Zat0() >= clipTop ||
rover->top.plane->Zat0() <= floorHeight ||
rover->bottom.plane->Zat0() >= ceilingHeight)
{
@ -773,7 +763,7 @@ namespace swrenderer
}
}
rw_pic = nullptr;
if (rover->top.plane->Zat0() <= clip3d->sclipBottom || passed)
if (rover->top.plane->Zat0() <= clipBottom || passed)
{ // maybe wall from inside rendering?
fover = nullptr;
for (j = 0; j < (int)frontsector->e->XFloor.ffloors.Size(); j++)
@ -790,8 +780,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible?
if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) continue; // no
if (fover->top.plane->Zat0() <= clip3d->sclipBottom)
if (fover->bottom.plane->Zat0() >= clipTop) continue; // no
if (fover->top.plane->Zat0() <= clipBottom)
{ // no, last possible
fover = nullptr;
break;
@ -842,8 +832,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible?
if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) continue; // no
if (fover->top.plane->Zat0() <= clip3d->sclipBottom)
if (fover->bottom.plane->Zat0() >= clipTop) continue; // no
if (fover->top.plane->Zat0() <= clipBottom)
{ // visible, last possible
fover = nullptr;
break;
@ -892,7 +882,7 @@ namespace swrenderer
{
for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{
if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0())
if (clipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0())
{
lightlist_t *lit = &backsector->e->XFloor.lightlist[j];
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
@ -906,7 +896,7 @@ namespace swrenderer
{
for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{
if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0())
if (clipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0())
{
lightlist_t *lit = &frontsector->e->XFloor.lightlist[j];
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
@ -921,7 +911,7 @@ namespace swrenderer
if (rw_pic != DONT_DRAW)
{
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap, clipTop, clipBottom);
}
else
{
@ -962,14 +952,13 @@ namespace swrenderer
top = MAX(frontcz1, frontcz2);
bot = MIN(frontfz1, frontfz2);
Clip3DFloors *clip3d = Thread->Clip3D.get();
if (clip3d->fake3D & FAKE3D_CLIPTOP)
if (m3DFloor.clipTop)
{
top = MIN(top, clip3d->sclipTop);
top = MIN(top, m3DFloor.sclipTop);
}
if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
if (m3DFloor.clipBottom)
{
bot = MAX(bot, clip3d->sclipBottom);
bot = MAX(bot, m3DFloor.sclipBottom);
}
}
}

View file

@ -32,14 +32,14 @@ namespace swrenderer
{
public:
RenderDrawSegment(RenderThread *thread);
void Render(DrawSegment *ds, int x1, int x2);
void Render(DrawSegment *ds, int x1, int x2, Fake3DTranslucent clip3DFloor);
RenderThread *Thread = nullptr;
private:
bool RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade, bool wrap);
bool RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade);
void ClipMidtex(int x1, int x2);
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap);
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap, double clipTop, double clipBottom);
void RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade);
void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot);
@ -47,6 +47,7 @@ namespace swrenderer
sector_t *backsector = nullptr;
seg_t *curline = nullptr;
Fake3DTranslucent m3DFloor;
FWallCoords WallC;
FWallTmapVals WallT;

View file

@ -99,7 +99,7 @@ namespace swrenderer
}
}
VisiblePlane *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap)
VisiblePlane *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha)
{
secplane_t plane;
VisiblePlane *check;
@ -140,8 +140,7 @@ namespace swrenderer
// kg3D - hack, store alpha in sky
// i know there is ->alpha, but this also allows to identify fake plane
// and ->alpha is for stacked sectors
Clip3DFloors *clip3d = Thread->Clip3D.get();
if (clip3d->fake3D & (FAKE3D_FAKEFLOOR | FAKE3D_FAKECEILING)) sky = 0x80000000 | clip3d->fakeAlpha;
if (fakeFloorType == Fake3DOpaque::FakeFloor || fakeFloorType == Fake3DOpaque::FakeCeiling) sky = 0x80000000 | fakeAlpha;
else sky = 0; // not skyflatnum so it can't be a sky
portal = nullptr;
alpha = OPAQUE;

View file

@ -40,7 +40,7 @@ namespace swrenderer
void Clear();
void ClearKeepFakePlanes();
VisiblePlane *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap);
VisiblePlane *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha);
VisiblePlane *GetRange(VisiblePlane *pl, int start, int stop);
bool HasPortalPlanes() const;

View file

@ -67,7 +67,6 @@ namespace swrenderer
FakeFloors.clear();
fakeActive = false;
fake3D = 0;
while (CurrentSkybox)
{
DeleteHeights();

View file

@ -33,24 +33,33 @@ namespace swrenderer
ClipStack *next;
};
enum Fake3DOpaque
// BSP stage
struct Fake3DOpaque
{
// BSP stage:
FAKE3D_FAKEFLOOR = 1, // fake floor, mark seg as FAKE
FAKE3D_FAKECEILING = 2, // fake ceiling, mark seg as FAKE
FAKE3D_FAKEBACK = 4, // RenderLine with fake backsector, mark seg as FAKE
FAKE3D_FAKEMASK = 7,
FAKE3D_CLIPBOTFRONT = 8, // use front sector clipping info (bottom)
FAKE3D_CLIPTOPFRONT = 16, // use front sector clipping info (top)
enum Type
{
Normal, // Not a 3D floor
FakeFloor, // fake floor, mark seg as FAKE
FakeCeiling, // fake ceiling, mark seg as FAKE
FakeBack // RenderLine with fake backsector, mark seg as FAKE
};
Type type = Normal;
bool clipBotFront = false; // use front sector clipping info (bottom)
bool clipTopFront = false; // use front sector clipping info (top)
Fake3DOpaque() { }
Fake3DOpaque(Type type) : type(type) { }
};
enum Fake3DTranslucent
// Drawing stage
struct Fake3DTranslucent
{
// sorting stage:
FAKE3D_CLIPBOTTOM = 1, // clip bottom
FAKE3D_CLIPTOP = 2, // clip top
FAKE3D_REFRESHCLIP = 4, // refresh clip info
FAKE3D_DOWN2UP = 8, // rendering from down to up (floors)
bool clipBottom = false;
bool clipTop = false;
bool down2Up = false; // rendering from down to up (floors)
double sclipBottom = 0;
double sclipTop = 0;
};
class FakeFloorClip
@ -82,13 +91,8 @@ namespace swrenderer
RenderThread *Thread = nullptr;
int fake3D = 0;
FakeFloorClip *fakeFloor = nullptr;
fixed_t fakeAlpha = 0;
bool fakeActive = false;
double sclipBottom = 0;
double sclipTop = 0;
HeightLevel *height_top = nullptr;
HeightLevel *height_cur = nullptr;
int CurrentSkybox = 0;

View file

@ -450,7 +450,7 @@ namespace swrenderer
}
// kg3D - add fake segs, never rendered
void RenderOpaquePass::FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap)
void RenderOpaquePass::FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque opaque3dfloor)
{
int count;
seg_t* line;
@ -462,7 +462,7 @@ namespace swrenderer
{
if ((line->sidedef) && !(line->sidedef->Flags & WALLF_POLYOBJ))
{
renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap);
renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap, opaque3dfloor);
}
line++;
}
@ -565,7 +565,9 @@ namespace swrenderer
frontsector->planes[sector_t::ceiling].xform,
frontsector->sky,
portal,
basecolormap
basecolormap,
Fake3DOpaque::Normal,
0
) : nullptr;
if (ceilingplane)
@ -606,7 +608,9 @@ namespace swrenderer
frontsector->planes[sector_t::floor].xform,
frontsector->sky,
portal,
basecolormap
basecolormap,
Fake3DOpaque::Normal,
0
) : nullptr;
if (floorplane)
@ -634,7 +638,7 @@ namespace swrenderer
if (!(clip3d->fakeFloor->fakeFloor->flags & FF_RENDERPLANES)) continue;
if (clip3d->fakeFloor->fakeFloor->alpha == 0) continue;
if (clip3d->fakeFloor->fakeFloor->flags & FF_THISINSIDE && clip3d->fakeFloor->fakeFloor->flags & FF_INVERTSECTOR) continue;
clip3d->fakeAlpha = MIN<fixed_t>(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE);
fixed_t fakeAlpha = MIN<fixed_t>(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE);
if (clip3d->fakeFloor->validcount != validcount)
{
clip3d->fakeFloor->validcount = validcount;
@ -644,7 +648,6 @@ namespace swrenderer
if (fakeHeight < Thread->Viewport->viewpoint.Pos.Z &&
fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot))
{
clip3d->fake3D = FAKE3D_FAKEFLOOR;
tempsec = *clip3d->fakeFloor->fakeFloor->model;
tempsec.floorplane = *clip3d->fakeFloor->fakeFloor->top.plane;
tempsec.ceilingplane = *clip3d->fakeFloor->fakeFloor->bottom.plane;
@ -672,13 +675,14 @@ namespace swrenderer
frontsector->planes[position].xform,
frontsector->sky,
nullptr,
basecolormap);
basecolormap,
Fake3DOpaque::FakeFloor,
fakeAlpha);
if (floorplane)
floorplane->AddLights(Thread, frontsector->lighthead);
FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap);
clip3d->fake3D = 0;
FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap, Fake3DOpaque::FakeFloor);
frontsector = sub->sector;
}
}
@ -696,7 +700,7 @@ namespace swrenderer
if (!(clip3d->fakeFloor->fakeFloor->flags & FF_RENDERPLANES)) continue;
if (clip3d->fakeFloor->fakeFloor->alpha == 0) continue;
if (!(clip3d->fakeFloor->fakeFloor->flags & FF_THISINSIDE) && (clip3d->fakeFloor->fakeFloor->flags & (FF_SWIMMABLE | FF_INVERTSECTOR)) == (FF_SWIMMABLE | FF_INVERTSECTOR)) continue;
clip3d->fakeAlpha = MIN<fixed_t>(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE);
fixed_t fakeAlpha = MIN<fixed_t>(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE);
if (clip3d->fakeFloor->validcount != validcount)
{
@ -707,7 +711,6 @@ namespace swrenderer
if (fakeHeight > Thread->Viewport->viewpoint.Pos.Z &&
fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot))
{
clip3d->fake3D = FAKE3D_FAKECEILING;
tempsec = *clip3d->fakeFloor->fakeFloor->model;
tempsec.floorplane = *clip3d->fakeFloor->fakeFloor->top.plane;
tempsec.ceilingplane = *clip3d->fakeFloor->fakeFloor->bottom.plane;
@ -738,13 +741,14 @@ namespace swrenderer
frontsector->planes[position].xform,
frontsector->sky,
nullptr,
basecolormap);
basecolormap,
Fake3DOpaque::FakeCeiling,
fakeAlpha);
if (ceilingplane)
ceilingplane->AddLights(Thread, frontsector->lighthead);
FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap);
clip3d->fake3D = 0;
FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap, Fake3DOpaque::FakeCeiling);
frontsector = sub->sector;
}
}
@ -787,7 +791,7 @@ namespace swrenderer
if (dist1 > line_distance_cull && dist2 > line_distance_cull)
{
FarClipLine farclip(Thread);
farclip.Render(line, InSubsector, floorplane, ceilingplane);
farclip.Render(line, InSubsector, floorplane, ceilingplane, Fake3DOpaque::Normal);
}
else if (!outersubsector || line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ))
{
@ -805,7 +809,7 @@ namespace swrenderer
if (!(clip3d->fakeFloor->fakeFloor->flags & FF_EXISTS)) continue;
if (!(clip3d->fakeFloor->fakeFloor->flags & FF_RENDERPLANES)) continue;
if (!clip3d->fakeFloor->fakeFloor->model) continue;
clip3d->fake3D = FAKE3D_FAKEBACK;
Fake3DOpaque opaque3dfloor = Fake3DOpaque::FakeBack;
tempsec = *clip3d->fakeFloor->fakeFloor->model;
tempsec.floorplane = *clip3d->fakeFloor->fakeFloor->top.plane;
tempsec.ceilingplane = *clip3d->fakeFloor->fakeFloor->bottom.plane;
@ -814,14 +818,13 @@ namespace swrenderer
clip3d->fakeFloor->validcount = validcount;
clip3d->NewClip();
}
renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane, foggy, basecolormap); // fake
renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane, foggy, basecolormap, opaque3dfloor); // fake
}
clip3d->fakeFloor = nullptr;
clip3d->fake3D = 0;
floorplane = backupfp;
ceilingplane = backupcp;
}
renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap); // now real
renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap, Fake3DOpaque::Normal); // now real
}
line++;
}

View file

@ -82,7 +82,7 @@ namespace swrenderer
bool CheckBBox(float *bspcoord);
void AddPolyobjs(subsector_t *sub);
void FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap);
void FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque opaque3dfloor);
void AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside, bool foggy, FDynamicColormap *basecolormap);

View file

@ -131,7 +131,7 @@ namespace swrenderer
return false;
}
void RenderTranslucentPass::DrawMaskedSingle(bool renew)
void RenderTranslucentPass::DrawMaskedSingle(bool renew, Fake3DTranslucent clip3DFloor)
{
RenderPortal *renderportal = Thread->Portal.get();
DrawSegmentList *drawseglist = Thread->DrawSegments.get();
@ -143,17 +143,12 @@ namespace swrenderer
if (sprite->IsCurrentPortalUniq(renderportal->CurrentPortalUniq))
{
sprite->Render(Thread);
sprite->Render(Thread, clip3DFloor);
}
}
// render any remaining masked mid textures
if (renew)
{
Thread->Clip3D->fake3D |= FAKE3D_REFRESHCLIP;
}
for (unsigned int index = 0; index != drawseglist->SegmentsCount(); index++)
{
DrawSegment *ds = drawseglist->Segment(index);
@ -161,12 +156,18 @@ namespace swrenderer
// [ZZ] the same as above
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
continue;
if (ds->maskedtexturecol != nullptr || ds->bFogBoundary)
if (ds->maskedtexturecol || ds->bFogBoundary)
{
RenderDrawSegment renderer(Thread);
renderer.Render(ds, ds->x1, ds->x2);
renderer.Render(ds, ds->x1, ds->x2, clip3DFloor);
if (renew && ds->bFogBoundary) // don't draw fogboundary again
ds->bFogBoundary = false;
if (renew && ds->sprclipped)
{
memcpy(ds->sprtopclip, ds->bkup, (ds->x2 - ds->x1) * sizeof(short));
ds->sprclipped = false;
}
}
}
}
@ -183,48 +184,49 @@ namespace swrenderer
Clip3DFloors *clip3d = Thread->Clip3D.get();
if (clip3d->height_top == nullptr)
{ // kg3D - no visible 3D floors, normal rendering
DrawMaskedSingle(false);
Fake3DTranslucent clip3DFloor;
DrawMaskedSingle(false, clip3DFloor);
}
else
{ // kg3D - correct sorting
// ceilings
for (HeightLevel *hl = clip3d->height_cur; hl != nullptr && hl->height >= Thread->Viewport->viewpoint.Pos.Z; hl = hl->prev)
{
Fake3DTranslucent clip3DFloor;
if (hl->next)
{
clip3d->fake3D = FAKE3D_CLIPBOTTOM | FAKE3D_CLIPTOP;
clip3d->sclipTop = hl->next->height;
clip3DFloor.clipTop = true;
clip3DFloor.sclipTop = hl->next->height;
}
else
{
clip3d->fake3D = FAKE3D_CLIPBOTTOM;
}
clip3d->sclipBottom = hl->height;
DrawMaskedSingle(true);
clip3DFloor.clipBottom = true;
clip3DFloor.sclipBottom = hl->height;
DrawMaskedSingle(true, clip3DFloor);
Thread->PlaneList->RenderHeight(hl->height);
}
// floors
clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP;
clip3d->sclipTop = clip3d->height_top->height;
DrawMaskedSingle(true);
{
Fake3DTranslucent clip3DFloor;
clip3DFloor.clipTop = true;
clip3DFloor.sclipTop = clip3d->height_top->height;
clip3DFloor.down2Up = true;
DrawMaskedSingle(true, clip3DFloor);
}
for (HeightLevel *hl = clip3d->height_top; hl != nullptr && hl->height < Thread->Viewport->viewpoint.Pos.Z; hl = hl->next)
{
Thread->PlaneList->RenderHeight(hl->height);
Fake3DTranslucent clip3DFloor;
if (hl->next)
{
clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM;
clip3d->sclipTop = hl->next->height;
clip3DFloor.clipTop = true;
clip3DFloor.sclipTop = hl->next->height;
}
else
{
clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPBOTTOM;
}
clip3d->sclipBottom = hl->height;
DrawMaskedSingle(true);
clip3DFloor.clipBottom = true;
clip3DFloor.sclipBottom = hl->height;
clip3DFloor.down2Up = true;
DrawMaskedSingle(true, clip3DFloor);
}
clip3d->DeleteHeights();
clip3d->fake3D = 0;
}
if (Thread->MainThread)

View file

@ -49,7 +49,7 @@ namespace swrenderer
private:
void CollectPortals();
void DrawMaskedSingle(bool renew);
void DrawMaskedSingle(bool renew, Fake3DTranslucent clip3DFloor);
TArray<DrawSegment *> portaldrawsegs;
};

View file

@ -47,6 +47,7 @@ namespace swrenderer
fixed_t *maskedtexturecol = nullptr;
float *swall = nullptr;
short *bkup = nullptr; // sprtopclip backup, for mid and fake textures
bool sprclipped = false; // True if draw segment was used for clipping sprites
FWallTmapVals tmapvals;

View file

@ -64,7 +64,7 @@ namespace swrenderer
this->idepth = idepth;
}
void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ)
void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
{
SWModelRenderer renderer(thread);
renderer.RenderModel(x, y, z, smf, actor);

View file

@ -40,7 +40,7 @@ namespace swrenderer
static void Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor);
protected:
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
bool IsModel() const override { return true; }
private:

View file

@ -225,7 +225,7 @@ namespace swrenderer
thread->SpriteList->Push(vis);
}
void RenderParticle::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ)
void RenderParticle::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
{
auto vis = this;
@ -239,7 +239,7 @@ namespace swrenderer
if (ycount <= 0 || countbase <= 0)
return;
DrawMaskedSegsBehindParticle(thread);
DrawMaskedSegsBehindParticle(thread, clip3DFloor);
uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->Light.ColormapNum << FRACBITS)));
@ -278,7 +278,7 @@ namespace swrenderer
}
}
void RenderParticle::DrawMaskedSegsBehindParticle(RenderThread *thread)
void RenderParticle::DrawMaskedSegsBehindParticle(RenderThread *thread, const Fake3DTranslucent &clip3DFloor)
{
// Draw any masked textures behind this particle so that when the
// particle is drawn, it will be in front of them.
@ -297,7 +297,7 @@ namespace swrenderer
if (ds->CurrentPortalUniq == CurrentPortalUniq)
{
RenderDrawSegment renderer(thread);
renderer.Render(ds, MAX<int>(ds->x1, x1), MIN<int>(ds->x2, x2));
renderer.Render(ds, MAX<int>(ds->x1, x1), MIN<int>(ds->x2, x2), clip3DFloor);
}
}
}

View file

@ -14,10 +14,10 @@ namespace swrenderer
protected:
bool IsParticle() const override { return true; }
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
private:
void DrawMaskedSegsBehindParticle(RenderThread *thread);
void DrawMaskedSegsBehindParticle(RenderThread *thread, const Fake3DTranslucent &clip3DFloor);
fixed_t xscale = 0;
fixed_t startfrac = 0; // horizontal position of x1

View file

@ -303,7 +303,7 @@ namespace swrenderer
thread->SpriteList->Push(vis);
}
void RenderSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int)
void RenderSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int, Fake3DTranslucent)
{
auto vis = this;

View file

@ -10,7 +10,7 @@ namespace swrenderer
static void Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap);
protected:
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
private:
fixed_t xscale = 0;

View file

@ -49,11 +49,11 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer
{
void VisibleSprite::Render(RenderThread *thread)
void VisibleSprite::Render(RenderThread *thread, Fake3DTranslucent clip3DFloor)
{
if (IsModel())
{
Render(thread, nullptr, nullptr, 0, 0);
Render(thread, nullptr, nullptr, 0, 0, clip3DFloor);
return;
}
@ -62,10 +62,8 @@ namespace swrenderer
VisibleSprite *spr = this;
int i;
int x1, x2;
short topclip, botclip;
short *clip1, *clip2;
FSWColormap *colormap = spr->Light.BaseColormap;
int colormapnum = spr->Light.ColormapNum;
F3DFloor *rover;
@ -76,10 +74,10 @@ namespace swrenderer
if (spr->IsParticle())
{
// kg3D - reject invisible parts
if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= clip3d->sclipBottom) return;
if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gpos.Z >= clip3d->sclipTop) return;
if (clip3DFloor.clipBottom && spr->gpos.Z <= clip3DFloor.sclipBottom) return;
if (clip3DFloor.clipTop && spr->gpos.Z >= clip3DFloor.sclipTop) return;
spr->Render(thread, nullptr, nullptr, 0, 0);
spr->Render(thread, nullptr, nullptr, 0, 0, clip3DFloor);
return;
}
@ -95,27 +93,29 @@ namespace swrenderer
return;
// kg3D - reject invisible parts
if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gzt <= clip3d->sclipBottom) return;
if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gzb >= clip3d->sclipTop) return;
if (clip3DFloor.clipBottom && spr->gzt <= clip3DFloor.sclipBottom) return;
if (clip3DFloor.clipTop && spr->gzb >= clip3DFloor.sclipTop) return;
// kg3D - correct colors now
CameraLight *cameraLight = CameraLight::Instance();
if (!cameraLight->FixedColormap() && cameraLight->FixedLightLevel() < 0 && spr->sector->e && spr->sector->e->XFloor.lightlist.Size())
{
if (!(clip3d->fake3D & FAKE3D_CLIPTOP))
{
clip3d->sclipTop = spr->sector->ceilingplane.ZatPoint(thread->Viewport->viewpoint.Pos);
}
double clipTop;
if (clip3DFloor.clipTop)
clipTop = clip3DFloor.clipTop;
else
clipTop = spr->sector->ceilingplane.ZatPoint(thread->Viewport->viewpoint.Pos);
sector_t *sec = nullptr;
FDynamicColormap *mybasecolormap = nullptr;
for (i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
for (int i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
{
if (clip3d->sclipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0())
if (clipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0())
{
rover = spr->sector->e->XFloor.lightlist[i].caster;
if (rover)
{
if (rover->flags & FF_DOUBLESHADOW && clip3d->sclipTop <= rover->bottom.plane->Zat0())
if (rover->flags & FF_DOUBLESHADOW && clipTop <= rover->bottom.plane->Zat0())
{
break;
}
@ -231,15 +231,15 @@ namespace swrenderer
}
}
if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
if (clip3DFloor.clipBottom)
{
if (!spr->IsVoxel())
{
double hz = clip3d->sclipBottom;
double hz = clip3DFloor.sclipBottom;
if (spr->fakefloor)
{
double floorz = spr->fakefloor->top.plane->Zat0();
if (viewport->viewpoint.Pos.Z > floorz && floorz == clip3d->sclipBottom)
if (viewport->viewpoint.Pos.Z > floorz && floorz == clip3DFloor.sclipBottom)
{
hz = spr->fakefloor->bottom.plane->Zat0();
}
@ -250,17 +250,17 @@ namespace swrenderer
botclip = MAX<short>(0, h);
}
}
hzb = MAX(hzb, clip3d->sclipBottom);
hzb = MAX(hzb, clip3DFloor.sclipBottom);
}
if (clip3d->fake3D & FAKE3D_CLIPTOP)
if (clip3DFloor.clipTop)
{
if (!spr->IsVoxel())
{
double hz = clip3d->sclipTop;
double hz = clip3DFloor.sclipTop;
if (spr->fakeceiling != nullptr)
{
double ceilingZ = spr->fakeceiling->bottom.plane->Zat0();
if (viewport->viewpoint.Pos.Z < ceilingZ && ceilingZ == clip3d->sclipTop)
if (viewport->viewpoint.Pos.Z < ceilingZ && ceilingZ == clip3DFloor.sclipTop)
{
hz = spr->fakeceiling->top.plane->Zat0();
}
@ -271,7 +271,7 @@ namespace swrenderer
topclip = short(MIN(h, viewheight));
}
}
hzt = MIN(hzt, clip3d->sclipTop);
hzt = MIN(hzt, clip3DFloor.sclipTop);
}
if (topclip >= botclip)
@ -281,14 +281,16 @@ namespace swrenderer
return;
}
i = x2 - x1;
clip1 = clipbot + x1;
clip2 = cliptop + x1;
do
{
*clip1++ = botclip;
*clip2++ = topclip;
} while (--i);
int i = x2 - x1;
short *clip1 = clipbot + x1;
short *clip2 = cliptop + x1;
do
{
*clip1++ = botclip;
*clip2++ = topclip;
} while (--i);
}
// Scan drawsegs from end to start for obscuring segs.
// The first drawseg that is closer than the sprite is the clip seg.
@ -320,7 +322,7 @@ namespace swrenderer
int r2 = MIN<int>(ds->x2, x2);
RenderDrawSegment renderer(thread);
renderer.Render(ds, r1, r2);
renderer.Render(ds, r1, r2, clip3DFloor);
}
}
}
@ -338,9 +340,9 @@ namespace swrenderer
int r2 = MIN<int>(group.x2, x2);
// Clip bottom
clip1 = clipbot + r1;
clip2 = group.sprbottomclip + r1 - group.x1;
i = r2 - r1;
short *clip1 = clipbot + r1;
const short *clip2 = group.sprbottomclip + r1 - group.x1;
int i = r2 - r1;
do
{
if (*clip1 > *clip2)
@ -398,9 +400,9 @@ namespace swrenderer
if (ds->silhouette & SIL_BOTTOM) //bottom sil
{
clip1 = clipbot + r1;
clip2 = ds->sprbottomclip + r1 - ds->x1;
i = r2 - r1;
short *clip1 = clipbot + r1;
const short *clip2 = ds->sprbottomclip + r1 - ds->x1;
int i = r2 - r1;
do
{
if (*clip1 > *clip2)
@ -412,9 +414,9 @@ namespace swrenderer
if (ds->silhouette & SIL_TOP) // top sil
{
clip1 = cliptop + r1;
clip2 = ds->sprtopclip + r1 - ds->x1;
i = r2 - r1;
short *clip1 = cliptop + r1;
const short *clip2 = ds->sprtopclip + r1 - ds->x1;
int i = r2 - r1;
do
{
if (*clip1 < *clip2)
@ -431,13 +433,14 @@ namespace swrenderer
if (!spr->IsVoxel())
{
spr->Render(thread, clipbot, cliptop, 0, 0);
spr->Render(thread, clipbot, cliptop, 0, 0, clip3DFloor);
}
else
{
// If it is completely clipped away, don't bother drawing it.
if (cliptop[x2] >= clipbot[x2])
{
int i;
for (i = x1; i < x2; ++i)
{
if (cliptop[i] < clipbot[i])
@ -464,7 +467,7 @@ namespace swrenderer
}
int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale);
int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
spr->Render(thread, cliptop, clipbot, minvoxely, maxvoxely);
spr->Render(thread, cliptop, clipbot, minvoxely, maxvoxely, clip3DFloor);
}
spr->Light.BaseColormap = colormap;
spr->Light.ColormapNum = colormapnum;

View file

@ -38,7 +38,7 @@ namespace swrenderer
VisibleSprite() { RenderStyle = STYLE_Normal; }
virtual ~VisibleSprite() { }
void Render(RenderThread *thread);
void Render(RenderThread *thread, Fake3DTranslucent clip3DFloor);
bool IsCurrentPortalUniq(int portalUniq) const { return CurrentPortalUniq == portalUniq; }
const FVector3 &WorldPos() const { return gpos; }
@ -54,7 +54,7 @@ namespace swrenderer
virtual bool IsWallSprite() const { return false; }
virtual bool IsModel() const { return false; }
virtual void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) = 0;
virtual void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) = 0;
FTexture *pic = nullptr;

View file

@ -205,7 +205,7 @@ namespace swrenderer
thread->SpriteList->Push(vis);
}
void RenderVoxel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ)
void RenderVoxel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
{
auto spr = this;
auto viewport = thread->Viewport.get();

View file

@ -64,7 +64,7 @@ namespace swrenderer
protected:
bool IsVoxel() const override { return true; }
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
private:
struct posang

View file

@ -145,7 +145,7 @@ namespace swrenderer
thread->SpriteList->Push(vis);
}
void RenderWallSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int)
void RenderWallSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int, Fake3DTranslucent)
{
auto spr = this;

View file

@ -14,7 +14,7 @@ namespace swrenderer
protected:
bool IsWallSprite() const override { return true; }
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
private:
static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);

View file

@ -1979,6 +1979,7 @@ MAPCOLORMNU_LOCKEDCOLOR = "Locked doors";
MAPCOLORMNU_INTRALEVELCOLOR = "Teleporter to the same map";
MAPCOLORMNU_INTERLEVELCOLOR = "Teleporter to a different map";
MAPCOLORMNU_SECRETSECTORCOLOR = "Secret sector";
MAPCOLORMNU_UNEXPLOREDSECRETCOLOR = "Unexplored secret";
MAPCOLORMNU_SPECIALWALLCOLOR = "Special trigger lines";
MAPCOLORMNU_CHEATMODE = "Cheat Mode";
MAPCOLORMNU_TSWALLCOLOR = "Invisible 2-sided walls";

View file

@ -1157,6 +1157,7 @@ OptionMenu MapColorMenu protected
ColorPicker "$MAPCOLORMNU_INTRALEVELCOLOR", "am_intralevelcolor"
ColorPicker "$MAPCOLORMNU_INTERLEVELCOLOR", "am_interlevelcolor"
ColorPicker "$MAPCOLORMNU_SECRETSECTORCOLOR", "am_secretsectorcolor"
ColorPicker "$MAPCOLORMNU_UNEXPLOREDSECRETCOLOR", "am_unexploredsecretcolor"
ColorPicker "$MAPCOLORMNU_SPECIALWALLCOLOR", "am_specialwallcolor"
ColorPicker "$MAPCOLORMNU_PORTAL", "am_portalcolor"
StaticText " "

View file

@ -146,7 +146,17 @@ class BaseStatusBar native ui
HUD_AltHud // Used for passing through popups to the alt hud
}
enum EHUDMSGLayer
{
HUDMSGLayer_OverHUD,
HUDMSGLayer_UnderHUD,
HUDMSGLayer_OverMap,
NUM_HUDMSGLAYERS,
HUDMSGLayer_Default = HUDMSGLayer_OverHUD,
};
enum DI_Flags
{
DI_SKIPICON = 0x1,
@ -297,7 +307,7 @@ class BaseStatusBar native ui
private HUDFont mSmallFont;
native void AttachMessage(HUDMessageBase msg);
native void AttachMessage(HUDMessageBase msg, uint msgid = 0, int layer = HUDMSGLayer_Default);
native HUDMessageBase DetachMessage(HUDMessageBase msg);
native HUDMessageBase DetachMessageID(uint msgid);
native void DetachAllMessages();