mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-15 23:40:52 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
50cd3fbef5
46 changed files with 426 additions and 266 deletions
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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)
|
||||
|
|
108
src/dthinker.cpp
108
src/dthinker.cpp
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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&);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -67,7 +67,6 @@ namespace swrenderer
|
|||
FakeFloors.clear();
|
||||
|
||||
fakeActive = false;
|
||||
fake3D = 0;
|
||||
while (CurrentSkybox)
|
||||
{
|
||||
DeleteHeights();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace swrenderer
|
|||
|
||||
private:
|
||||
void CollectPortals();
|
||||
void DrawMaskedSingle(bool renew);
|
||||
void DrawMaskedSingle(bool renew, Fake3DTranslucent clip3DFloor);
|
||||
|
||||
TArray<DrawSegment *> portaldrawsegs;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 " "
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue