mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-16 16:01:06 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
ac858de40f
59 changed files with 780 additions and 512 deletions
|
@ -115,7 +115,8 @@ if( WIN32 )
|
|||
comdlg32
|
||||
ws2_32
|
||||
setupapi
|
||||
oleaut32 )
|
||||
oleaut32
|
||||
dbghelp )
|
||||
|
||||
if( NOT ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} DelayImp )
|
||||
|
|
|
@ -1259,7 +1259,6 @@ public:
|
|||
void LinkToWorld (FLinkContext *ctx, bool spawningmapthing=false, sector_t *sector = NULL);
|
||||
void UnlinkFromWorld(FLinkContext *ctx);
|
||||
void AdjustFloorClip ();
|
||||
bool InStateSequence(FState * newstate, FState * basestate);
|
||||
bool IsMapActor();
|
||||
int GetTics(FState * newstate);
|
||||
bool SetState (FState *newstate, bool nofunction=false);
|
||||
|
|
|
@ -1853,6 +1853,16 @@ static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char
|
|||
sc.MustGetString();
|
||||
DoomStartupInfo.Song = sc.String;
|
||||
}
|
||||
else if (!nextKey.CompareNoCase("LOADLIGHTS"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
DoomStartupInfo.LoadLights = !!sc.Number;
|
||||
}
|
||||
else if (!nextKey.CompareNoCase("LOADBRIGHTMAPS"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
DoomStartupInfo.LoadBrightmaps = !!sc.Number;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Silently ignore unknown properties
|
||||
|
@ -2022,13 +2032,13 @@ static void AddAutoloadFiles(const char *autoname)
|
|||
// [SP] Dialog reaction - load lights.pk3 and brightmaps.pk3 based on user choices
|
||||
if (!(gameinfo.flags & GI_SHAREWARE))
|
||||
{
|
||||
if (autoloadlights)
|
||||
if (DoomStartupInfo.LoadLights == 1 || (DoomStartupInfo.LoadLights != 0 && autoloadlights))
|
||||
{
|
||||
const char *lightswad = BaseFileSearch ("lights.pk3", NULL);
|
||||
if (lightswad)
|
||||
D_AddFile (allwads, lightswad);
|
||||
}
|
||||
if (autoloadbrightmaps)
|
||||
if (DoomStartupInfo.LoadBrightmaps == 1 || (DoomStartupInfo.LoadBrightmaps != 0 && autoloadbrightmaps))
|
||||
{
|
||||
const char *bmwad = BaseFileSearch ("brightmaps.pk3", NULL);
|
||||
if (bmwad)
|
||||
|
@ -2712,8 +2722,9 @@ void D_DoomMain (void)
|
|||
LightDefaults.DeleteAndClear(); // this can leak heap memory if it isn't cleared.
|
||||
|
||||
// delete DoomStartupInfo data
|
||||
DoomStartupInfo.Name = (const char*)0;
|
||||
DoomStartupInfo.Name = "";
|
||||
DoomStartupInfo.BkColor = DoomStartupInfo.FgColor = DoomStartupInfo.Type = 0;
|
||||
DoomStartupInfo.LoadLights = DoomStartupInfo.LoadBrightmaps = -1;
|
||||
|
||||
GC::FullGC(); // clean up before taking down the object list.
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ struct FStartupInfo
|
|||
uint32_t BkColor; // Background color for title banner
|
||||
FString Song;
|
||||
int Type;
|
||||
int LoadLights = -1;
|
||||
int LoadBrightmaps = -1;
|
||||
enum
|
||||
{
|
||||
DefaultStartup,
|
||||
|
|
|
@ -425,7 +425,7 @@ AActor &AActor::operator= (const AActor &other)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool AActor::InStateSequence(FState * newstate, FState * basestate)
|
||||
static int InStateSequence(FState * newstate, FState * basestate)
|
||||
{
|
||||
if (basestate == NULL) return false;
|
||||
|
||||
|
@ -440,12 +440,19 @@ bool AActor::InStateSequence(FState * newstate, FState * basestate)
|
|||
return false;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, InStateSequence)
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, InStateSequence, InStateSequence)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER(newstate, FState);
|
||||
PARAM_POINTER(basestate, FState);
|
||||
ACTION_RETURN_BOOL(self->InStateSequence(newstate, basestate));
|
||||
ACTION_RETURN_BOOL(InStateSequence(newstate, basestate));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FState, InStateSequence, InStateSequence)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FState);
|
||||
PARAM_POINTER(basestate, FState);
|
||||
ACTION_RETURN_BOOL(InStateSequence(self, basestate));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -151,8 +151,8 @@ void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, ui
|
|||
dest_height = new_dest_height;
|
||||
dest_pitch = new_dest_pitch;
|
||||
dest_bgra = new_dest_bgra;
|
||||
numa_start_y = numa_node * dest_height / num_numa_nodes;
|
||||
numa_end_y = (numa_node + 1) * dest_height / num_numa_nodes;
|
||||
numa_start_y = numa_node * screen->GetHeight() / num_numa_nodes;
|
||||
numa_end_y = (numa_node + 1) * screen->GetHeight() / num_numa_nodes;
|
||||
ccw = true;
|
||||
weaponScene = false;
|
||||
}
|
||||
|
|
|
@ -31,12 +31,7 @@
|
|||
#include "polyrenderer/scene/poly_light.h"
|
||||
|
||||
EXTERN_CVAR(Float, skyoffset)
|
||||
|
||||
extern double skytexturemid;
|
||||
extern float skyiscale;
|
||||
extern double skyscale;
|
||||
extern fixed_t sky1cyl, sky2cyl;
|
||||
|
||||
EXTERN_CVAR(Int, r_skymode)
|
||||
|
||||
PolySkyDome::PolySkyDome()
|
||||
{
|
||||
|
@ -292,6 +287,53 @@ static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true)
|
|||
|
||||
void PolySkySetup::Update()
|
||||
{
|
||||
double skytexturemid = 0.0;
|
||||
double skyscale = 0.0;
|
||||
float skyiscale = 0.0f;
|
||||
fixed_t sky1cyl = 0, sky2cyl = 0;
|
||||
|
||||
auto skytex1 = TexMan.GetPalettedTexture(sky1texture, true);
|
||||
auto skytex2 = TexMan.GetPalettedTexture(sky2texture, true);
|
||||
|
||||
if (skytex1)
|
||||
{
|
||||
FSoftwareTexture *sskytex1 = skytex1->GetSoftwareTexture();
|
||||
FSoftwareTexture *sskytex2 = skytex2->GetSoftwareTexture();
|
||||
skytexturemid = 0;
|
||||
int skyheight = skytex1->GetDisplayHeight();
|
||||
if (skyheight >= 128 && skyheight < 200)
|
||||
{
|
||||
skytexturemid = -28;
|
||||
}
|
||||
else if (skyheight > 200)
|
||||
{
|
||||
skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0);
|
||||
}
|
||||
|
||||
if (viewwidth != 0 && viewheight != 0)
|
||||
{
|
||||
skyiscale = float(r_Yaspect / freelookviewheight);
|
||||
skyscale = freelookviewheight / r_Yaspect;
|
||||
|
||||
skyiscale *= float(r_viewpoint.FieldOfView.Degrees / 90.);
|
||||
skyscale *= float(90. / r_viewpoint.FieldOfView.Degrees);
|
||||
}
|
||||
|
||||
if (skystretch)
|
||||
{
|
||||
skyscale *= (double)SKYSTRETCH_HEIGHT / skyheight;
|
||||
skyiscale *= skyheight / (float)SKYSTRETCH_HEIGHT;
|
||||
skytexturemid *= skyheight / (double)SKYSTRETCH_HEIGHT;
|
||||
}
|
||||
|
||||
// The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees,
|
||||
// giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024,
|
||||
// we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of
|
||||
// the texture as the cylinder's circumfrence.
|
||||
sky1cyl = MAX(sskytex1->GetWidth(), fixed_t(sskytex1->GetScale().X * 1024));
|
||||
sky2cyl = MAX(sskytex2->GetWidth(), fixed_t(sskytex2->GetScale().Y * 1024));
|
||||
}
|
||||
|
||||
FTextureID sky1tex, sky2tex;
|
||||
double frontdpos = 0, backdpos = 0;
|
||||
|
||||
|
|
|
@ -871,6 +871,7 @@ class GLDefsParser
|
|||
sc.ScriptError("Name longer than 8 characters: %s\n", sc.String);
|
||||
}
|
||||
frameName = sc.String;
|
||||
frameName.ToUpper();
|
||||
|
||||
startDepth = ScriptDepth;
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
code.setLogger(&logger);
|
||||
|
||||
JitCompiler compiler(&code, sfunc);
|
||||
CCFunc *func = compiler.Codegen();
|
||||
|
||||
return reinterpret_cast<JitFuncPtr>(AddJitFunction(&code, func));
|
||||
return reinterpret_cast<JitFuncPtr>(AddJitFunction(&code, &compiler));
|
||||
}
|
||||
catch (const CRecoverableError &e)
|
||||
{
|
||||
|
@ -100,6 +98,8 @@ asmjit::CCFunc *JitCompiler::Codegen()
|
|||
{
|
||||
Setup();
|
||||
|
||||
int lastLine = -1;
|
||||
|
||||
pc = sfunc->Code;
|
||||
auto end = pc + sfunc->CodeSize;
|
||||
while (pc != end)
|
||||
|
@ -107,10 +107,24 @@ asmjit::CCFunc *JitCompiler::Codegen()
|
|||
int i = (int)(ptrdiff_t)(pc - sfunc->Code);
|
||||
op = pc->op;
|
||||
|
||||
int curLine = sfunc->PCToLine(pc);
|
||||
if (curLine != lastLine)
|
||||
{
|
||||
lastLine = curLine;
|
||||
|
||||
auto label = cc.newLabel();
|
||||
cc.bind(label);
|
||||
|
||||
JitLineInfo info;
|
||||
info.Label = label;
|
||||
info.LineNumber = curLine;
|
||||
LineInfo.Push(info);
|
||||
}
|
||||
|
||||
if (op != OP_PARAM && op != OP_PARAMI && op != OP_VTBL)
|
||||
{
|
||||
FString lineinfo;
|
||||
lineinfo.Format("; line %d: %02x%02x%02x%02x %s", sfunc->PCToLine(pc), pc->op, pc->a, pc->b, pc->c, OpNames[op]);
|
||||
lineinfo.Format("; line %d: %02x%02x%02x%02x %s", curLine, pc->op, pc->a, pc->b, pc->c, OpNames[op]);
|
||||
cc.comment("", 0);
|
||||
cc.comment(lineinfo.GetChars(), lineinfo.Len());
|
||||
}
|
||||
|
@ -127,6 +141,21 @@ asmjit::CCFunc *JitCompiler::Codegen()
|
|||
cc.endFunc();
|
||||
cc.finalize();
|
||||
|
||||
auto code = cc.getCode ();
|
||||
for (unsigned int j = 0; j < LineInfo.Size (); j++)
|
||||
{
|
||||
auto info = LineInfo[j];
|
||||
|
||||
if (!code->isLabelValid (info.Label))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
info.InstructionIndex = code->getLabelOffset (info.Label);
|
||||
|
||||
LineInfo[j] = info;
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
|
||||
JitFuncPtr JitCompile(VMScriptFunction *func);
|
||||
void JitDumpLog(FILE *file, VMScriptFunction *func);
|
||||
FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames);
|
||||
|
|
|
@ -2,6 +2,25 @@
|
|||
#include "jit.h"
|
||||
#include "jitintern.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <DbgHelp.h>
|
||||
#else
|
||||
#include <execinfo.h>
|
||||
#include <cxxabi.h>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
struct JitFuncInfo
|
||||
{
|
||||
FString name;
|
||||
FString filename;
|
||||
TArray<JitLineInfo> LineInfo;
|
||||
void *start;
|
||||
void *end;
|
||||
};
|
||||
|
||||
static TArray<JitFuncInfo> JitDebugInfo;
|
||||
static TArray<uint8_t*> JitBlocks;
|
||||
static TArray<uint8_t*> JitFrames;
|
||||
static size_t JitBlockPos = 0;
|
||||
|
@ -230,10 +249,12 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
|
|||
return info;
|
||||
}
|
||||
|
||||
void *AddJitFunction(asmjit::CodeHolder* code, asmjit::CCFunc *func)
|
||||
void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
|
||||
{
|
||||
using namespace asmjit;
|
||||
|
||||
CCFunc *func = compiler->Codegen();
|
||||
|
||||
size_t codeSize = code->getCodeSize();
|
||||
if (codeSize == 0)
|
||||
return nullptr;
|
||||
|
@ -271,11 +292,17 @@ void *AddJitFunction(asmjit::CodeHolder* code, asmjit::CCFunc *func)
|
|||
RUNTIME_FUNCTION *table = (RUNTIME_FUNCTION*)(unwindptr + unwindInfoSize);
|
||||
table[0].BeginAddress = (DWORD)(ptrdiff_t)(startaddr - baseaddr);
|
||||
table[0].EndAddress = (DWORD)(ptrdiff_t)(endaddr - baseaddr);
|
||||
#ifndef __MINGW64__
|
||||
table[0].UnwindInfoAddress = (DWORD)(ptrdiff_t)(unwindptr - baseaddr);
|
||||
#else
|
||||
table[0].UnwindData = (DWORD)(ptrdiff_t)(unwindptr - baseaddr);
|
||||
#endif
|
||||
BOOLEAN result = RtlAddFunctionTable(table, 1, (DWORD64)baseaddr);
|
||||
JitFrames.Push((uint8_t*)table);
|
||||
if (result == 0)
|
||||
I_Error("RtlAddFunctionTable failed");
|
||||
|
||||
JitDebugInfo.Push({ compiler->GetScriptFunction()->PrintableName, compiler->GetScriptFunction()->SourceFileName, compiler->LineInfo, startaddr, endaddr });
|
||||
#endif
|
||||
|
||||
return p;
|
||||
|
@ -287,52 +314,6 @@ extern "C"
|
|||
{
|
||||
void __register_frame(const void*);
|
||||
void __deregister_frame(const void*);
|
||||
|
||||
#if 0 // Someone needs to implement this if GDB/LLDB should produce correct call stacks
|
||||
|
||||
// GDB JIT interface (GG guys! Thank you SO MUCH for not hooking into the above functions. Really appreciate it!)
|
||||
|
||||
// To register code with GDB, the JIT should follow this protocol:
|
||||
//
|
||||
// * Generate an object file in memory with symbols and other desired debug information.
|
||||
// The file must include the virtual addresses of the sections.
|
||||
// * Create a code entry for the file, which gives the start and size of the symbol file.
|
||||
// * Add it to the linked list in the JIT descriptor.
|
||||
// * Point the relevant_entry field of the descriptor at the entry.
|
||||
// * Set action_flag to JIT_REGISTER and call __jit_debug_register_code.
|
||||
|
||||
// Pure beauty! Now a JIT also has to create a full ELF object file. And is it a MACH-O on macOS? You guys ROCK!
|
||||
|
||||
typedef enum
|
||||
{
|
||||
JIT_NOACTION = 0,
|
||||
JIT_REGISTER_FN,
|
||||
JIT_UNREGISTER_FN
|
||||
} jit_actions_t;
|
||||
|
||||
struct jit_code_entry
|
||||
{
|
||||
struct jit_code_entry *next_entry;
|
||||
struct jit_code_entry *prev_entry;
|
||||
const char *symfile_addr;
|
||||
uint64_t symfile_size;
|
||||
};
|
||||
|
||||
struct jit_descriptor
|
||||
{
|
||||
uint32_t version;
|
||||
// This type should be jit_actions_t, but we use uint32_t to be explicit about the bitwidth.
|
||||
uint32_t action_flag;
|
||||
struct jit_code_entry *relevant_entry;
|
||||
struct jit_code_entry *first_entry;
|
||||
};
|
||||
|
||||
// GDB puts a breakpoint in this function.
|
||||
void __attribute__((noinline)) __jit_debug_register_code() { };
|
||||
|
||||
// Make sure to specify the version statically, because the debugger may check the version before we can set it.
|
||||
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
|
||||
#endif
|
||||
}
|
||||
|
||||
static void WriteLength(TArray<uint8_t> &stream, unsigned int pos, unsigned int v)
|
||||
|
@ -664,10 +645,12 @@ static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::CCFunc *func, unsigned int &
|
|||
return stream;
|
||||
}
|
||||
|
||||
void *AddJitFunction(asmjit::CodeHolder* code, asmjit::CCFunc *func)
|
||||
void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
|
||||
{
|
||||
using namespace asmjit;
|
||||
|
||||
CCFunc *func = compiler->Codegen();
|
||||
|
||||
size_t codeSize = code->getCodeSize();
|
||||
if (codeSize == 0)
|
||||
return nullptr;
|
||||
|
@ -743,6 +726,8 @@ void *AddJitFunction(asmjit::CodeHolder* code, asmjit::CCFunc *func)
|
|||
#endif
|
||||
}
|
||||
|
||||
JitDebugInfo.Push({ compiler->GetScriptFunction()->PrintableName, compiler->GetScriptFunction()->SourceFileName, compiler->LineInfo, startaddr, endaddr });
|
||||
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
@ -764,8 +749,219 @@ void JitRelease()
|
|||
{
|
||||
asmjit::OSUtils::releaseVirtualMemory(p, 1024 * 1024);
|
||||
}
|
||||
JitDebugInfo.Clear();
|
||||
JitFrames.Clear();
|
||||
JitBlocks.Clear();
|
||||
JitBlockPos = 0;
|
||||
JitBlockSize = 0;
|
||||
}
|
||||
|
||||
static int CaptureStackTrace(int max_frames, void **out_frames)
|
||||
{
|
||||
memset(out_frames, 0, sizeof(void *) * max_frames);
|
||||
|
||||
#ifdef _WIN64
|
||||
// RtlCaptureStackBackTrace doesn't support RtlAddFunctionTable..
|
||||
|
||||
CONTEXT context;
|
||||
RtlCaptureContext(&context);
|
||||
|
||||
UNWIND_HISTORY_TABLE history;
|
||||
memset(&history, 0, sizeof(UNWIND_HISTORY_TABLE));
|
||||
|
||||
ULONG64 establisherframe = 0;
|
||||
PVOID handlerdata = nullptr;
|
||||
|
||||
int frame;
|
||||
for (frame = 0; frame < max_frames; frame++)
|
||||
{
|
||||
ULONG64 imagebase;
|
||||
PRUNTIME_FUNCTION rtfunc = RtlLookupFunctionEntry(context.Rip, &imagebase, &history);
|
||||
|
||||
KNONVOLATILE_CONTEXT_POINTERS nvcontext;
|
||||
memset(&nvcontext, 0, sizeof(KNONVOLATILE_CONTEXT_POINTERS));
|
||||
if (!rtfunc)
|
||||
{
|
||||
// Leaf function
|
||||
context.Rip = (ULONG64)(*(PULONG64)context.Rsp);
|
||||
context.Rsp += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlVirtualUnwind(UNW_FLAG_NHANDLER, imagebase, context.Rip, rtfunc, &context, &handlerdata, &establisherframe, &nvcontext);
|
||||
}
|
||||
|
||||
if (!context.Rip)
|
||||
break;
|
||||
|
||||
out_frames[frame] = (void*)context.Rip;
|
||||
}
|
||||
return frame;
|
||||
|
||||
#elif defined(WIN32)
|
||||
// JIT isn't supported here, so just do nothing.
|
||||
return 0;//return RtlCaptureStackBackTrace(0, MIN(max_frames, 32), out_frames, nullptr);
|
||||
#else
|
||||
return backtrace(out_frames, max_frames);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
class NativeSymbolResolver
|
||||
{
|
||||
public:
|
||||
NativeSymbolResolver() { SymInitialize(GetCurrentProcess(), nullptr, TRUE); }
|
||||
~NativeSymbolResolver() { SymCleanup(GetCurrentProcess()); }
|
||||
|
||||
FString GetName(void *frame)
|
||||
{
|
||||
FString s;
|
||||
|
||||
unsigned char buffer[sizeof(IMAGEHLP_SYMBOL64) + 128];
|
||||
IMAGEHLP_SYMBOL64 *symbol64 = reinterpret_cast<IMAGEHLP_SYMBOL64*>(buffer);
|
||||
memset(symbol64, 0, sizeof(IMAGEHLP_SYMBOL64) + 128);
|
||||
symbol64->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
|
||||
symbol64->MaxNameLength = 128;
|
||||
|
||||
DWORD64 displacement = 0;
|
||||
BOOL result = SymGetSymFromAddr64(GetCurrentProcess(), (DWORD64)frame, &displacement, symbol64);
|
||||
if (result)
|
||||
{
|
||||
IMAGEHLP_LINE64 line64;
|
||||
DWORD displacement = 0;
|
||||
memset(&line64, 0, sizeof(IMAGEHLP_LINE64));
|
||||
line64.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
result = SymGetLineFromAddr64(GetCurrentProcess(), (DWORD64)frame, &displacement, &line64);
|
||||
if (result)
|
||||
{
|
||||
s.Format("Called from %s at %s, line %d\n", symbol64->Name, line64.FileName, (int)line64.LineNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.Format("Called from %s\n", symbol64->Name);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
#else
|
||||
class NativeSymbolResolver
|
||||
{
|
||||
public:
|
||||
FString GetName(void *frame)
|
||||
{
|
||||
FString s;
|
||||
char **strings;
|
||||
void *frames[1] = { frame };
|
||||
strings = backtrace_symbols(frames, 1);
|
||||
|
||||
// Decode the strings
|
||||
char *ptr = strings[0];
|
||||
char *filename = ptr;
|
||||
const char *function = "";
|
||||
|
||||
// Find function name
|
||||
while (*ptr)
|
||||
{
|
||||
if (*ptr == '(') // Found function name
|
||||
{
|
||||
*(ptr++) = 0;
|
||||
function = ptr;
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
// Find offset
|
||||
if (function[0]) // Only if function was found
|
||||
{
|
||||
while (*ptr)
|
||||
{
|
||||
if (*ptr == '+') // Found function offset
|
||||
{
|
||||
*(ptr++) = 0;
|
||||
break;
|
||||
}
|
||||
if (*ptr == ')') // Not found function offset, but found, end of function
|
||||
{
|
||||
*(ptr++) = 0;
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
int status;
|
||||
char *new_function = abi::__cxa_demangle(function, nullptr, nullptr, &status);
|
||||
if (new_function) // Was correctly decoded
|
||||
{
|
||||
function = new_function;
|
||||
}
|
||||
|
||||
s.Format("Called from %s at %s\n", function, filename);
|
||||
|
||||
if (new_function)
|
||||
{
|
||||
free(new_function);
|
||||
}
|
||||
|
||||
free(strings);
|
||||
return s;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
int JITPCToLine(uint8_t *pc, const JitFuncInfo *info)
|
||||
{
|
||||
int PCIndex = int(pc - ((uint8_t *) (info->start)));
|
||||
if (info->LineInfo.Size () == 1) return info->LineInfo[0].LineNumber;
|
||||
for (unsigned i = 1; i < info->LineInfo.Size (); i++)
|
||||
{
|
||||
if (info->LineInfo[i].InstructionIndex >= PCIndex)
|
||||
{
|
||||
return info->LineInfo[i - 1].LineNumber;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
FString JitGetStackFrameName(NativeSymbolResolver *nativeSymbols, void *pc)
|
||||
{
|
||||
for (unsigned int i = 0; i < JitDebugInfo.Size(); i++)
|
||||
{
|
||||
const auto &info = JitDebugInfo[i];
|
||||
if (pc >= info.start && pc < info.end)
|
||||
{
|
||||
int line = JITPCToLine ((uint8_t *)pc, &info);
|
||||
|
||||
FString s;
|
||||
|
||||
if (line == -1)
|
||||
s.Format("Called from %s at %s\n", info.name.GetChars(), info.filename.GetChars());
|
||||
else
|
||||
s.Format("Called from %s at %s, line %d\n", info.name.GetChars(), info.filename.GetChars(), line);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
return nativeSymbols ? nativeSymbols->GetName(pc) : FString();
|
||||
}
|
||||
|
||||
FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames)
|
||||
{
|
||||
void *frames[32];
|
||||
int numframes = CaptureStackTrace(32, frames);
|
||||
|
||||
std::unique_ptr<NativeSymbolResolver> nativeSymbols;
|
||||
if (includeNativeFrames)
|
||||
nativeSymbols.reset(new NativeSymbolResolver());
|
||||
|
||||
FString s;
|
||||
for (int i = framesToSkip + 1; i < numframes; i++)
|
||||
{
|
||||
s += JitGetStackFrameName(nativeSymbols.get(), frames[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,22 @@ extern int VMCalls[10];
|
|||
#define ABCs (pc[0].i24)
|
||||
#define JMPOFS(x) ((x)->i24)
|
||||
|
||||
struct JitLineInfo
|
||||
{
|
||||
ptrdiff_t InstructionIndex = 0;
|
||||
int32_t LineNumber = -1;
|
||||
asmjit::Label Label;
|
||||
};
|
||||
|
||||
class JitCompiler
|
||||
{
|
||||
public:
|
||||
JitCompiler(asmjit::CodeHolder *code, VMScriptFunction *sfunc) : cc(code), sfunc(sfunc) { }
|
||||
|
||||
asmjit::CCFunc *Codegen();
|
||||
VMScriptFunction *GetScriptFunction() { return sfunc; }
|
||||
|
||||
TArray<JitLineInfo> LineInfo;
|
||||
|
||||
private:
|
||||
// Declare EmitXX functions for the opcodes:
|
||||
|
@ -308,5 +318,5 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void *AddJitFunction(asmjit::CodeHolder* code, asmjit::CCFunc *func);
|
||||
void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler);
|
||||
asmjit::CodeInfo GetHostCodeInfo();
|
||||
|
|
|
@ -658,7 +658,11 @@ CVMAbortException::CVMAbortException(EVMAbortException reason, const char *morei
|
|||
size_t len = strlen(m_Message);
|
||||
myvsnprintf(m_Message + len, MAX_ERRORTEXT - len, moreinfo, ap);
|
||||
}
|
||||
stacktrace = "";
|
||||
|
||||
if (vm_jit)
|
||||
stacktrace = JitCaptureStackTrace(1, false);
|
||||
else
|
||||
stacktrace = "";
|
||||
}
|
||||
|
||||
// Print this only once on the first catch block.
|
||||
|
|
|
@ -1427,6 +1427,35 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, LookForPlayers, P_LookForPlayers)
|
|||
ACTION_RETURN_BOOL(P_LookForPlayers(self, allaround, params));
|
||||
}
|
||||
|
||||
static int CheckMonsterUseSpecials(AActor *self)
|
||||
{
|
||||
spechit_t spec;
|
||||
int good = 0;
|
||||
|
||||
if (!(self->flags6 & MF6_NOTRIGGER))
|
||||
{
|
||||
while (spechit.Pop (spec))
|
||||
{
|
||||
// [RH] let monsters push lines, as well as use them
|
||||
if (((self->flags4 & MF4_CANUSEWALLS) && P_ActivateLine (spec.line, self, 0, SPAC_Use)) ||
|
||||
((self->flags2 & MF2_PUSHWALL) && P_ActivateLine (spec.line, self, 0, SPAC_Push)))
|
||||
{
|
||||
good |= spec.line == self->BlockingLine ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else spechit.Clear();
|
||||
|
||||
return good;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckMonsterUseSpecials, CheckMonsterUseSpecials)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
||||
ACTION_RETURN_INT(CheckMonsterUseSpecials(self));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_Wander, A_Wander)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
@ -1587,6 +1616,37 @@ DEFINE_ACTION_FUNCTION_NATIVE(AKey, GetKeyType, P_GetKeyType)
|
|||
ACTION_RETURN_POINTER(P_GetKeyType(num));
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
//
|
||||
// 3D Floor exports
|
||||
//
|
||||
//=====================================================================================
|
||||
int CheckFor3DFloorHit(AActor *self, double z, bool trigger)
|
||||
{
|
||||
return P_CheckFor3DFloorHit(self, z, trigger);
|
||||
}
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckFor3DFloorHit, CheckFor3DFloorHit)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_FLOAT(z);
|
||||
PARAM_BOOL(trigger);
|
||||
|
||||
ACTION_RETURN_BOOL(P_CheckFor3DFloorHit(self, z, trigger));
|
||||
}
|
||||
|
||||
int CheckFor3DCeilingHit(AActor *self, double z, bool trigger)
|
||||
{
|
||||
return P_CheckFor3DCeilingHit(self, z, trigger);
|
||||
}
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckFor3DCeilingHit, CheckFor3DCeilingHit)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_FLOAT(z);
|
||||
PARAM_BOOL(trigger);
|
||||
|
||||
ACTION_RETURN_BOOL(P_CheckFor3DCeilingHit(self, z, trigger));
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFINE_FIELD(AActor, snext)
|
||||
|
|
|
@ -73,6 +73,7 @@ enum EMIDIType
|
|||
|
||||
extern int MUSHeaderSearch(const uint8_t *head, int len);
|
||||
void I_InitSoundFonts();
|
||||
extern "C" void dumb_exit();
|
||||
|
||||
EXTERN_CVAR (Int, snd_samplerate)
|
||||
EXTERN_CVAR (Int, snd_mididevice)
|
||||
|
@ -127,8 +128,6 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
|
||||
void I_InitMusic (void)
|
||||
{
|
||||
static bool setatterm = false;
|
||||
|
||||
I_InitSoundFonts();
|
||||
|
||||
snd_musicvolume.Callback ();
|
||||
|
@ -139,12 +138,6 @@ void I_InitMusic (void)
|
|||
I_InitMusicWin32 ();
|
||||
#endif // _WIN32
|
||||
|
||||
if (!setatterm)
|
||||
{
|
||||
setatterm = true;
|
||||
atterm (I_ShutdownMusicExit);
|
||||
|
||||
}
|
||||
MusicDown = false;
|
||||
}
|
||||
|
||||
|
@ -170,15 +163,10 @@ void I_ShutdownMusic(bool onexit)
|
|||
{
|
||||
WildMidi_Shutdown();
|
||||
TimidityPP_Shutdown();
|
||||
dumb_exit();
|
||||
}
|
||||
}
|
||||
|
||||
void I_ShutdownMusicExit()
|
||||
{
|
||||
I_ShutdownMusic(true);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -45,7 +45,6 @@ struct FOptionValues;
|
|||
//
|
||||
void I_InitMusic ();
|
||||
void I_ShutdownMusic (bool onexit = false);
|
||||
void I_ShutdownMusicExit ();
|
||||
void I_BuildMIDIMenuList (FOptionValues *);
|
||||
void I_UpdateMusic ();
|
||||
|
||||
|
|
|
@ -287,6 +287,7 @@ void I_CloseSound ()
|
|||
|
||||
void I_ShutdownSound()
|
||||
{
|
||||
I_ShutdownMusic(true);
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
S_StopAllChannels();
|
||||
|
|
|
@ -774,8 +774,6 @@ MusInfo *MOD_OpenSong(FileReader &reader)
|
|||
bool is_it = false;
|
||||
bool is_dos = true;
|
||||
|
||||
atterm(dumb_exit);
|
||||
|
||||
int size = (int)reader.GetLength();
|
||||
auto fpos = reader.Tell();
|
||||
|
||||
|
|
|
@ -247,7 +247,6 @@ void initialize_resampler_coeffs(void)
|
|||
static bool done = false;
|
||||
if (done) return;
|
||||
done = true;
|
||||
// atterm(free_gauss_table);
|
||||
|
||||
initialize_newton_coeffs();
|
||||
initialize_gauss_table(gauss_n);
|
||||
|
|
|
@ -558,21 +558,6 @@ namespace swrenderer
|
|||
int32_t frac = args.TextureVPos();
|
||||
int32_t fracstep = args.TextureVStep();
|
||||
|
||||
if (!args.FadeSky())
|
||||
{
|
||||
int count = thread->count_for_thread(args.DestY(), args.Count());
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
|
||||
*dest = source0[sample_index];
|
||||
dest += pitch;
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
|
||||
|
@ -594,6 +579,21 @@ namespace swrenderer
|
|||
fracstep *= num_cores;
|
||||
pitch *= num_cores;
|
||||
|
||||
if (!args.FadeSky())
|
||||
{
|
||||
count = thread->count_for_thread(args.DestY(), args.Count());
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
|
||||
*dest = source0[sample_index];
|
||||
dest += pitch;
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t solid_top = args.SolidTopColor();
|
||||
uint32_t solid_bottom = args.SolidBottomColor();
|
||||
|
||||
|
@ -686,7 +686,6 @@ namespace swrenderer
|
|||
void DrawDoubleSky1PalCommand::Execute(DrawerThread *thread)
|
||||
{
|
||||
uint8_t *dest = args.Dest();
|
||||
int count = args.Count();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
const uint8_t *source0 = args.FrontTexturePixels();
|
||||
const uint8_t *source1 = args.BackTexturePixels();
|
||||
|
@ -696,6 +695,10 @@ namespace swrenderer
|
|||
int32_t frac = args.TextureVPos();
|
||||
int32_t fracstep = args.TextureVStep();
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
|
||||
|
||||
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
|
||||
int start_fade = 2; // How fast it should fade out
|
||||
int fade_length = (1 << (24 - start_fade));
|
||||
|
@ -708,8 +711,6 @@ namespace swrenderer
|
|||
start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
|
||||
end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
dest = thread->dest_for_thread(args.DestY(), pitch, dest);
|
||||
frac += fracstep * skipped;
|
||||
fracstep *= num_cores;
|
||||
|
|
|
@ -50,21 +50,6 @@ namespace swrenderer
|
|||
uint32_t solid_bottom = args.SolidBottomColor();
|
||||
bool fadeSky = args.FadeSky();
|
||||
|
||||
if (!fadeSky)
|
||||
{
|
||||
int count = thread->count_for_thread(args.DestY(), args.Count());
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
|
||||
*dest = source0[sample_index];
|
||||
dest += pitch;
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
|
||||
|
@ -86,6 +71,21 @@ namespace swrenderer
|
|||
fracstep *= num_cores;
|
||||
pitch *= num_cores;
|
||||
|
||||
if (!fadeSky)
|
||||
{
|
||||
int count = thread->count_for_thread(args.DestY(), args.Count());
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
|
||||
*dest = source0[sample_index];
|
||||
dest += pitch;
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BgraColor solid_top_fill = solid_top;
|
||||
BgraColor solid_bottom_fill = solid_bottom;
|
||||
|
||||
|
@ -172,7 +172,6 @@ namespace swrenderer
|
|||
void Execute(DrawerThread *thread) override
|
||||
{
|
||||
uint32_t *dest = (uint32_t *)args.Dest();
|
||||
int count = args.Count();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels();
|
||||
const uint32_t *source1 = (const uint32_t *)args.BackTexturePixels();
|
||||
|
@ -181,7 +180,11 @@ namespace swrenderer
|
|||
|
||||
int32_t frac = args.TextureVPos();
|
||||
int32_t fracstep = args.TextureVStep();
|
||||
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
|
||||
|
||||
uint32_t solid_top = args.SolidTopColor();
|
||||
uint32_t solid_bottom = args.SolidBottomColor();
|
||||
bool fadeSky = args.FadeSky();
|
||||
|
@ -198,8 +201,6 @@ namespace swrenderer
|
|||
start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
|
||||
end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
dest = thread->dest_for_thread(args.DestY(), pitch, dest);
|
||||
frac += fracstep * skipped;
|
||||
fracstep *= num_cores;
|
||||
|
|
|
@ -49,21 +49,6 @@ namespace swrenderer
|
|||
uint32_t solid_bottom = args.SolidBottomColor();
|
||||
bool fadeSky = args.FadeSky();
|
||||
|
||||
if (!fadeSky)
|
||||
{
|
||||
int count = thread->count_for_thread(args.DestY(), args.Count());
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
|
||||
*dest = source0[sample_index];
|
||||
dest += pitch;
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
|
||||
|
@ -85,6 +70,21 @@ namespace swrenderer
|
|||
fracstep *= num_cores;
|
||||
pitch *= num_cores;
|
||||
|
||||
if (!fadeSky)
|
||||
{
|
||||
int count = thread->count_for_thread(args.DestY(), args.Count());
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
|
||||
*dest = source0[sample_index];
|
||||
dest += pitch;
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128());
|
||||
__m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128());
|
||||
|
||||
|
@ -167,7 +167,6 @@ namespace swrenderer
|
|||
void Execute(DrawerThread *thread) override
|
||||
{
|
||||
uint32_t *dest = (uint32_t *)args.Dest();
|
||||
int count = args.Count();
|
||||
int pitch = args.Viewport()->RenderTarget->GetPitch();
|
||||
const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels();
|
||||
const uint32_t *source1 = (const uint32_t *)args.BackTexturePixels();
|
||||
|
@ -176,7 +175,11 @@ namespace swrenderer
|
|||
|
||||
int32_t frac = args.TextureVPos();
|
||||
int32_t fracstep = args.TextureVStep();
|
||||
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
|
||||
|
||||
uint32_t solid_top = args.SolidTopColor();
|
||||
uint32_t solid_bottom = args.SolidBottomColor();
|
||||
bool fadeSky = args.FadeSky();
|
||||
|
@ -193,8 +196,6 @@ namespace swrenderer
|
|||
start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
|
||||
end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
|
||||
|
||||
int num_cores = thread->num_cores;
|
||||
int skipped = thread->skipped_by_thread(args.DestY());
|
||||
dest = thread->dest_for_thread(args.DestY(), pitch, dest);
|
||||
frac += fracstep * skipped;
|
||||
fracstep *= num_cores;
|
||||
|
|
|
@ -140,8 +140,8 @@ void DrawerThreads::WorkerMain(DrawerThread *thread)
|
|||
// Grab the commands
|
||||
DrawerCommandQueuePtr list = active_commands[thread->current_queue];
|
||||
thread->current_queue++;
|
||||
thread->numa_start_y = thread->numa_node * viewheight / thread->num_numa_nodes;
|
||||
thread->numa_end_y = (thread->numa_node + 1) * viewheight / thread->num_numa_nodes;
|
||||
thread->numa_start_y = thread->numa_node * screen->GetHeight() / thread->num_numa_nodes;
|
||||
thread->numa_end_y = (thread->numa_node + 1) * screen->GetHeight() / thread->num_numa_nodes;
|
||||
start_lock.unlock();
|
||||
|
||||
// Do the work:
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
// Active range for the numa block the cores are part of
|
||||
int numa_start_y = 0;
|
||||
int numa_end_y = 0;
|
||||
int numa_end_y = MAXHEIGHT;
|
||||
|
||||
// Working buffer used by the tilted (sloped) span drawer
|
||||
const uint8_t *tiltlighting[MAXWIDTH];
|
||||
|
|
|
@ -74,7 +74,8 @@ namespace swrenderer
|
|||
fillshort(spanend + t2, b2 - t2, x);
|
||||
}
|
||||
|
||||
drawerargs.SetLight(basecolormap, (float)light, lightlevel, foggy, thread->Viewport.get());
|
||||
drawerargs.SetBaseColormap(basecolormap);
|
||||
drawerargs.SetLight(light, lightlevel, foggy, thread->Viewport.get());
|
||||
|
||||
uint8_t *fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT);
|
||||
|
||||
|
@ -101,7 +102,7 @@ namespace swrenderer
|
|||
fillshort(spanend + t2, b2 - t2, x);
|
||||
}
|
||||
rcolormap = lcolormap;
|
||||
drawerargs.SetLight(basecolormap, (float)light, wallshade);
|
||||
drawerargs.SetLight(light, wallshade);
|
||||
fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1164,24 +1164,10 @@ namespace swrenderer
|
|||
offset = -offset;
|
||||
}
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
drawerargs.SetStyle(false, false, OPAQUE);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1);
|
||||
|
||||
FLightNode *light_list = (mLineSegment && mLineSegment->sidedef) ? mLineSegment->sidedef->lighthead : nullptr;
|
||||
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || (cameraLight->FixedColormap() != nullptr))
|
||||
light_list = nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, lightlevel, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, false, OPAQUE, lightlevel, offset, rw_light, rw_lightstep, GetLightList(), foggy, basecolormap);
|
||||
}
|
||||
|
||||
void SWRenderLine::RenderMiddleTexture(int x1, int x2)
|
||||
|
@ -1211,24 +1197,10 @@ namespace swrenderer
|
|||
offset = -offset;
|
||||
}
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
drawerargs.SetStyle(false, false, OPAQUE);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1);
|
||||
|
||||
FLightNode *light_list = (mLineSegment && mLineSegment->sidedef) ? mLineSegment->sidedef->lighthead : nullptr;
|
||||
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || (cameraLight->FixedColormap() != nullptr))
|
||||
light_list = nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, lightlevel, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, lightlevel, offset, rw_light, rw_lightstep, GetLightList(), foggy, basecolormap);
|
||||
}
|
||||
|
||||
void SWRenderLine::RenderBottomTexture(int x1, int x2)
|
||||
|
@ -1259,24 +1231,21 @@ namespace swrenderer
|
|||
offset = -offset;
|
||||
}
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
drawerargs.SetStyle(false, false, OPAQUE);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1);
|
||||
|
||||
FLightNode *light_list = (mLineSegment && mLineSegment->sidedef) ? mLineSegment->sidedef->lighthead : nullptr;
|
||||
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || (cameraLight->FixedColormap() != nullptr))
|
||||
light_list = nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, lightlevel, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
renderWallpart.Render(mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, false, OPAQUE, lightlevel, offset, rw_light, rw_lightstep, GetLightList(), foggy, basecolormap);
|
||||
}
|
||||
|
||||
FLightNode *SWRenderLine::GetLightList()
|
||||
{
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || cameraLight->FixedColormap())
|
||||
return nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
else if (mLineSegment && mLineSegment->sidedef)
|
||||
return mLineSegment->sidedef->lighthead;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -91,6 +91,8 @@ namespace swrenderer
|
|||
void RenderMiddleTexture(int x1, int x2);
|
||||
void RenderBottomTexture(int x1, int x2);
|
||||
|
||||
FLightNode *GetLightList();
|
||||
|
||||
bool IsFogBoundary(sector_t *front, sector_t *back) const;
|
||||
bool SkyboxCompare(sector_t *frontsector, sector_t *backsector) const;
|
||||
|
||||
|
|
|
@ -70,21 +70,6 @@ namespace swrenderer
|
|||
curline = ds->curline;
|
||||
m3DFloor = clip3DFloor;
|
||||
|
||||
float alpha = (float)MIN(curline->linedef->alpha, 1.);
|
||||
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
|
||||
|
||||
WallDrawerArgs walldrawerargs;
|
||||
walldrawerargs.SetStyle(true, additive, FLOAT2FIXED(alpha));
|
||||
|
||||
SpriteDrawerArgs columndrawerargs;
|
||||
FDynamicColormap *patchstylecolormap = nullptr;
|
||||
bool visible = columndrawerargs.SetStyle(viewport, LegacyRenderStyles[additive ? STYLE_Add : STYLE_Translucent], alpha, 0, 0, patchstylecolormap);
|
||||
|
||||
if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Thread->MainThread)
|
||||
NetUpdate();
|
||||
|
||||
|
@ -97,29 +82,38 @@ namespace swrenderer
|
|||
|
||||
FDynamicColormap *basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap
|
||||
|
||||
bool foggy = ds->foggy;
|
||||
int lightlevel = ds->lightlevel;
|
||||
rw_lightstep = ds->lightstep;
|
||||
rw_light = ds->light + (x1 - ds->x1) * rw_lightstep;
|
||||
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
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--)
|
||||
{
|
||||
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 (clipTop <= 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]);
|
||||
//bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag
|
||||
lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr);
|
||||
break;
|
||||
}
|
||||
lightlist_t *lit = &frontsector->e->XFloor.lightlist[i];
|
||||
basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]);
|
||||
foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag
|
||||
lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float alpha = (float)MIN(curline->linedef->alpha, 1.);
|
||||
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
|
||||
|
||||
SpriteDrawerArgs columndrawerargs;
|
||||
ColormapLight cmlight;
|
||||
cmlight.SetColormap(Thread, MINZ, lightlevel, foggy, basecolormap, false, false, false, false, false);
|
||||
bool visible = columndrawerargs.SetStyle(viewport, LegacyRenderStyles[additive ? STYLE_Add : STYLE_Translucent], alpha, 0, 0, cmlight);
|
||||
if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// [RH] Draw fog partition
|
||||
bool renderwall = true;
|
||||
bool notrelevant = false;
|
||||
|
@ -140,7 +134,7 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
if (renderwall)
|
||||
notrelevant = RenderWall(ds, x1, x2, walldrawerargs, columndrawerargs, visible, basecolormap, lightlevel);
|
||||
notrelevant = RenderWall(ds, x1, x2, basecolormap, columndrawerargs, visible, lightlevel, foggy);
|
||||
|
||||
if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls())
|
||||
{
|
||||
|
@ -153,7 +147,7 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int lightlevel)
|
||||
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, FDynamicColormap *basecolormap, SpriteDrawerArgs &columndrawerargs, bool visible, int lightlevel, bool foggy)
|
||||
{
|
||||
auto renderstyle = DefaultRenderStyle();
|
||||
auto viewport = Thread->Viewport.get();
|
||||
|
@ -178,18 +172,6 @@ namespace swrenderer
|
|||
double spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
|
||||
float rw_scalestep = ds->iscalestep;
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
{
|
||||
walldrawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
columndrawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
}
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
{
|
||||
walldrawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
columndrawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
}
|
||||
|
||||
// find positioning
|
||||
double texheight = tex->GetScaledHeightDouble();
|
||||
double texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid));
|
||||
|
@ -328,16 +310,17 @@ namespace swrenderer
|
|||
mfloorclip = walllower.ScreenY;
|
||||
mceilingclip = wallupper.ScreenY;
|
||||
|
||||
auto cameraLight = CameraLight::Instance();
|
||||
bool needslight = (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0);
|
||||
|
||||
// draw the columns one at a time
|
||||
if (visible)
|
||||
{
|
||||
Thread->PrepareTexture(tex, renderstyle);
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0)
|
||||
{
|
||||
columndrawerargs.SetLight(basecolormap, rw_light, lightlevel, ds->foggy, Thread->Viewport.get());
|
||||
}
|
||||
if (needslight)
|
||||
columndrawerargs.SetLight(rw_light, lightlevel, foggy, Thread->Viewport.get());
|
||||
|
||||
fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY);
|
||||
double sprtopscreen;
|
||||
|
@ -412,8 +395,11 @@ namespace swrenderer
|
|||
double top, bot;
|
||||
GetMaskedWallTopBottom(ds, top, bot);
|
||||
|
||||
float alpha = FLOAT2FIXED((float)MIN(curline->linedef->alpha, 1.));
|
||||
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(walldrawerargs, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
|
||||
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, additive, alpha, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -430,9 +416,6 @@ namespace swrenderer
|
|||
if (Alpha <= 0)
|
||||
return;
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
drawerargs.SetStyle(true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha);
|
||||
|
||||
rw_lightstep = ds->lightstep;
|
||||
rw_light = ds->light + (x1 - ds->x1) * rw_lightstep;
|
||||
|
||||
|
@ -486,12 +469,6 @@ namespace swrenderer
|
|||
texturemid += rowoffset;
|
||||
}
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
WallC.sz1 = ds->sz1;
|
||||
WallC.sz2 = ds->sz2;
|
||||
WallC.sx1 = ds->sx1;
|
||||
|
@ -524,7 +501,7 @@ namespace swrenderer
|
|||
GetMaskedWallTopBottom(ds, top, bot);
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
|
||||
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
|
||||
|
||||
RenderDecal::RenderDecals(Thread, curline->sidedef, ds, lightlevel, rw_light, rw_lightstep, curline, WallC, ds->foggy, basecolormap, wallupper.ScreenY, walllower.ScreenY, true);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace swrenderer
|
|||
RenderThread *Thread = nullptr;
|
||||
|
||||
private:
|
||||
bool RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int lightlevel);
|
||||
bool RenderWall(DrawSegment *ds, int x1, int x2, FDynamicColormap *basecolormap, SpriteDrawerArgs &columndrawerargs, bool visible, int lightlevel, bool foggy);
|
||||
void ClipMidtex(int x1, int x2);
|
||||
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int lightlevel, FDynamicColormap *basecolormap, double clipTop, double clipBottom);
|
||||
void RenderFakeWallRange(DrawSegment *ds, int x1, int x2);
|
||||
|
|
|
@ -341,16 +341,19 @@ namespace swrenderer
|
|||
|
||||
drawerargs.SetTextureFracBits(Thread->Viewport->RenderTarget->IsBgra() ? FRACBITS : fracbits);
|
||||
|
||||
// Textures that aren't masked can use the faster opaque drawer
|
||||
if (!rw_pic->GetTexture()->isMasked() && mask && alpha >= OPAQUE && !additive)
|
||||
{
|
||||
drawerargs.SetStyle(true, false, OPAQUE, basecolormap);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawerargs.SetStyle(mask, additive, alpha, basecolormap);
|
||||
}
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
bool fixed = (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0);
|
||||
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, cameraLight->FixedLightLevelShade());
|
||||
else if (cameraLight->FixedColormap())
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
else
|
||||
drawerargs.SetLight(basecolormap, 0, 0);
|
||||
|
||||
float dx = WallC.tright.X - WallC.tleft.X;
|
||||
float dy = WallC.tright.Y - WallC.tleft.Y;
|
||||
float length = sqrt(dx * dx + dy * dy);
|
||||
|
@ -369,7 +372,7 @@ namespace swrenderer
|
|||
continue;
|
||||
|
||||
if (!fixed)
|
||||
drawerargs.SetLight(basecolormap, curlight, lightlevel, foggy, Thread->Viewport.get());
|
||||
drawerargs.SetLight(curlight, lightlevel, foggy, Thread->Viewport.get());
|
||||
|
||||
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x]));
|
||||
|
||||
|
@ -425,12 +428,6 @@ namespace swrenderer
|
|||
|
||||
void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal)
|
||||
{
|
||||
// Textures that aren't masked can use the faster ProcessNormalWall.
|
||||
if (!rw_pic->GetTexture()->isMasked() && drawerargs.IsMaskedDrawer())
|
||||
{
|
||||
drawerargs.SetStyle(true, false, OPAQUE);
|
||||
}
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
|
||||
{
|
||||
|
@ -514,9 +511,8 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void RenderWallPart::Render(const WallDrawerArgs &drawerargs, sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FSoftwareTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int lightlevel, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap)
|
||||
void RenderWallPart::Render(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FSoftwareTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, bool additive, fixed_t alpha, int lightlevel, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap)
|
||||
{
|
||||
this->drawerargs = drawerargs;
|
||||
this->x1 = x1;
|
||||
this->x2 = x2;
|
||||
this->frontsector = frontsector;
|
||||
|
@ -532,6 +528,8 @@ namespace swrenderer
|
|||
this->light_list = light_list;
|
||||
this->rw_pic = pic;
|
||||
this->mask = mask;
|
||||
this->additive = additive;
|
||||
this->alpha = alpha;
|
||||
|
||||
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace swrenderer
|
|||
RenderWallPart(RenderThread *thread);
|
||||
|
||||
void Render(
|
||||
const WallDrawerArgs &drawerargs,
|
||||
sector_t *frontsector,
|
||||
seg_t *curline,
|
||||
const FWallCoords &WallC,
|
||||
|
@ -62,6 +61,8 @@ namespace swrenderer
|
|||
double top,
|
||||
double bottom,
|
||||
bool mask,
|
||||
bool additive,
|
||||
fixed_t alpha,
|
||||
int lightlevel,
|
||||
fixed_t xoffset,
|
||||
float light,
|
||||
|
@ -96,6 +97,8 @@ namespace swrenderer
|
|||
FDynamicColormap *basecolormap = nullptr;
|
||||
FLightNode *light_list = nullptr;
|
||||
bool mask = false;
|
||||
bool additive = false;
|
||||
fixed_t alpha = 0;
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
};
|
||||
|
|
|
@ -134,29 +134,14 @@ namespace swrenderer
|
|||
|
||||
planeheight = fabs(pl->height.Zat0() - Thread->Viewport->viewpoint.Pos.Z);
|
||||
|
||||
basecolormap = colormap;
|
||||
|
||||
// [RH] set foggy flag
|
||||
foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE));
|
||||
foggy = (level.fadeto || colormap->Fade || (level.flags & LEVEL_HASFADETABLE));
|
||||
lightlevel = pl->lightlevel;
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
{
|
||||
drawerargs.SetLight(basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
plane_shade = false;
|
||||
}
|
||||
else if (cameraLight->FixedColormap())
|
||||
{
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
plane_shade = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
plane_shade = true;
|
||||
lightlevel = pl->lightlevel;
|
||||
}
|
||||
plane_shade = cameraLight->FixedLightLevel() < 0 && !cameraLight->FixedColormap();
|
||||
|
||||
drawerargs.SetStyle(masked, additive, alpha);
|
||||
drawerargs.SetStyle(masked, additive, alpha, colormap);
|
||||
|
||||
light_list = pl->lights;
|
||||
|
||||
|
@ -200,7 +185,7 @@ namespace swrenderer
|
|||
if (plane_shade)
|
||||
{
|
||||
// Determine lighting based on the span's distance from the viewer.
|
||||
drawerargs.SetLight(basecolormap, (float)Thread->Light->FlatPlaneVis(y, planeheight, foggy, viewport), lightlevel, foggy, viewport);
|
||||
drawerargs.SetLight((float)Thread->Light->FlatPlaneVis(y, planeheight, foggy, viewport), lightlevel, foggy, viewport);
|
||||
}
|
||||
|
||||
if (r_dynlights)
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace swrenderer
|
|||
bool plane_shade;
|
||||
int lightlevel;
|
||||
bool foggy;
|
||||
FDynamicColormap *basecolormap;
|
||||
double pviewx, pviewy;
|
||||
double xstepscale, ystepscale;
|
||||
double basexfrac, baseyfrac;
|
||||
|
|
|
@ -57,65 +57,8 @@
|
|||
CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
EXTERN_CVAR(Int, r_skymode)
|
||||
|
||||
|
||||
double skytexturemid;
|
||||
double skyscale;
|
||||
float skyiscale;
|
||||
fixed_t sky1cyl, sky2cyl;
|
||||
|
||||
void InitSoftwareSky()
|
||||
{
|
||||
auto skytex1 = TexMan.GetPalettedTexture(sky1texture, true);
|
||||
auto skytex2 = TexMan.GetPalettedTexture(sky2texture, true);
|
||||
|
||||
if (skytex1 == nullptr)
|
||||
return;
|
||||
|
||||
// Note: I don't think it is good that this stuff gets cached globally.
|
||||
// For something that only needs to be once per frame it is rather pointless and makes it hard to swap out the underlying textures based on user settings.
|
||||
FSoftwareTexture *sskytex1 = skytex1->GetSoftwareTexture();
|
||||
FSoftwareTexture *sskytex2 = skytex2->GetSoftwareTexture();
|
||||
skytexturemid = 0;
|
||||
int skyheight = skytex1->GetDisplayHeight();
|
||||
if (skyheight >= 128 && skyheight < 200)
|
||||
{
|
||||
skytexturemid = -28;
|
||||
}
|
||||
else if (skyheight > 200)
|
||||
{
|
||||
skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0);
|
||||
}
|
||||
|
||||
if (viewwidth != 0 && viewheight != 0)
|
||||
{
|
||||
skyiscale = float(r_Yaspect / freelookviewheight);
|
||||
skyscale = freelookviewheight / r_Yaspect;
|
||||
|
||||
skyiscale *= float(r_viewpoint.FieldOfView.Degrees / 90.);
|
||||
skyscale *= float(90. / r_viewpoint.FieldOfView.Degrees);
|
||||
}
|
||||
|
||||
if (skystretch)
|
||||
{
|
||||
skyscale *= (double)SKYSTRETCH_HEIGHT / skyheight;
|
||||
skyiscale *= skyheight / (float)SKYSTRETCH_HEIGHT;
|
||||
skytexturemid *= skyheight / (double)SKYSTRETCH_HEIGHT;
|
||||
}
|
||||
|
||||
// The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees,
|
||||
// giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024,
|
||||
// we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of
|
||||
// the texture as the cylinder's circumfrence.
|
||||
sky1cyl = MAX(sskytex1->GetWidth(), fixed_t(sskytex1->GetScale().X * 1024));
|
||||
sky2cyl = MAX(sskytex2->GetWidth(), fixed_t(sskytex2->GetScale().Y * 1024));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
|
||||
static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true)
|
||||
{
|
||||
auto tex = TexMan.GetPalettedTexture(texid, true);
|
||||
|
@ -127,6 +70,48 @@ namespace swrenderer
|
|||
RenderSkyPlane::RenderSkyPlane(RenderThread *thread)
|
||||
{
|
||||
Thread = thread;
|
||||
|
||||
auto skytex1 = TexMan.GetPalettedTexture(sky1texture, true);
|
||||
auto skytex2 = TexMan.GetPalettedTexture(sky2texture, true);
|
||||
|
||||
if (skytex1 == nullptr)
|
||||
return;
|
||||
|
||||
FSoftwareTexture *sskytex1 = skytex1->GetSoftwareTexture();
|
||||
FSoftwareTexture *sskytex2 = skytex2->GetSoftwareTexture();
|
||||
skytexturemid = 0;
|
||||
int skyheight = skytex1->GetDisplayHeight();
|
||||
if (skyheight >= 128 && skyheight < 200)
|
||||
{
|
||||
skytexturemid = -28;
|
||||
}
|
||||
else if (skyheight > 200)
|
||||
{
|
||||
skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0);
|
||||
}
|
||||
|
||||
if (viewwidth != 0 && viewheight != 0)
|
||||
{
|
||||
skyiscale = float(r_Yaspect / freelookviewheight);
|
||||
skyscale = freelookviewheight / r_Yaspect;
|
||||
|
||||
skyiscale *= float(r_viewpoint.FieldOfView.Degrees / 90.);
|
||||
skyscale *= float(90. / r_viewpoint.FieldOfView.Degrees);
|
||||
}
|
||||
|
||||
if (skystretch)
|
||||
{
|
||||
skyscale *= (double)SKYSTRETCH_HEIGHT / skyheight;
|
||||
skyiscale *= skyheight / (float)SKYSTRETCH_HEIGHT;
|
||||
skytexturemid *= skyheight / (double)SKYSTRETCH_HEIGHT;
|
||||
}
|
||||
|
||||
// The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees,
|
||||
// giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024,
|
||||
// we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of
|
||||
// the texture as the cylinder's circumfrence.
|
||||
sky1cyl = MAX(sskytex1->GetWidth(), fixed_t(sskytex1->GetScale().X * 1024));
|
||||
sky2cyl = MAX(sskytex2->GetWidth(), fixed_t(sskytex2->GetScale().Y * 1024));
|
||||
}
|
||||
|
||||
void RenderSkyPlane::Render(VisiblePlane *pl)
|
||||
|
@ -227,15 +212,7 @@ namespace swrenderer
|
|||
backpos = int(fmod(backdpos, sky2cyl * 65536.0));
|
||||
}
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedColormap())
|
||||
{
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawerargs.SetLight(&NormalLight, 0, 0);
|
||||
}
|
||||
drawerargs.SetStyle();
|
||||
|
||||
Thread->PrepareTexture(frontskytex, DefaultRenderStyle());
|
||||
Thread->PrepareTexture(backskytex, DefaultRenderStyle());
|
||||
|
|
|
@ -41,6 +41,11 @@ namespace swrenderer
|
|||
void DrawSkyColumnStripe(int start_x, int y1, int y2, double scale, double texturemid, double yrepeat);
|
||||
void DrawSkyColumn(int start_x, int y1, int y2);
|
||||
|
||||
double skytexturemid;
|
||||
double skyscale;
|
||||
float skyiscale;
|
||||
fixed_t sky1cyl, sky2cyl;
|
||||
|
||||
FSoftwareTexture *frontskytex = nullptr;
|
||||
FSoftwareTexture *backskytex = nullptr;
|
||||
angle_t skyflip = 0;
|
||||
|
|
|
@ -174,31 +174,19 @@ namespace swrenderer
|
|||
|
||||
// [RH] set foggy flag
|
||||
basecolormap = colormap;
|
||||
foggy = level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE);;
|
||||
foggy = level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE);
|
||||
|
||||
planelightfloat = (Thread->Light->SlopePlaneGlobVis(foggy) * lxscale * lyscale) / (fabs(pl->height.ZatPoint(Thread->Viewport->viewpoint.Pos) - Thread->Viewport->viewpoint.Pos.Z)) / 65536.f;
|
||||
|
||||
if (pl->height.fC() > 0)
|
||||
planelightfloat = -planelightfloat;
|
||||
|
||||
drawerargs.SetStyle(false, false, OPAQUE, basecolormap);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
{
|
||||
drawerargs.SetLight(basecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
plane_shade = false;
|
||||
}
|
||||
else if (cameraLight->FixedColormap())
|
||||
{
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
plane_shade = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawerargs.SetLight(basecolormap, 0, 0);
|
||||
plane_shade = true;
|
||||
lightlevel = pl->lightlevel;
|
||||
}
|
||||
plane_shade = cameraLight->FixedLightLevel() < 0 && !cameraLight->FixedColormap();
|
||||
|
||||
lightlevel = pl->lightlevel;
|
||||
|
||||
// Hack in support for 1 x Z and Z x 1 texture sizes
|
||||
if (drawerargs.TextureHeightBits() == 0)
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
// [RH] Base blending values (for e.g. underwater)
|
||||
int BaseBlendR, BaseBlendG, BaseBlendB;
|
||||
float BaseBlendA;
|
||||
void InitSoftwareSky();
|
||||
|
||||
|
||||
|
||||
|
@ -87,7 +86,6 @@ SWSceneDrawer::~SWSceneDrawer()
|
|||
sector_t *SWSceneDrawer::RenderView(player_t *player)
|
||||
{
|
||||
// Avoid using the pixel buffer from the last frame
|
||||
InitSoftwareSky(); // do this here to avoid problems when texture modes are changed on the fly.
|
||||
FBTextureIndex = (FBTextureIndex + 1) % 2;
|
||||
auto &fbtex = FBTexture[FBTextureIndex];
|
||||
|
||||
|
|
|
@ -74,8 +74,6 @@ namespace swrenderer
|
|||
double zpos;
|
||||
int needrepeat = 0;
|
||||
sector_t *back;
|
||||
bool calclighting;
|
||||
bool rereadcolormap;
|
||||
FDynamicColormap *usecolormap;
|
||||
float light = 0;
|
||||
const short *mfloorclip;
|
||||
|
@ -259,15 +257,12 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
// Prepare lighting
|
||||
calclighting = false;
|
||||
usecolormap = basecolormap;
|
||||
rereadcolormap = true;
|
||||
|
||||
// Decals that are added to the scene must fade to black.
|
||||
if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
||||
{
|
||||
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
|
||||
rereadcolormap = false;
|
||||
}
|
||||
|
||||
light = lightleft + (x1 - savecoord.sx1) * lightstep;
|
||||
|
@ -292,24 +287,12 @@ namespace swrenderer
|
|||
{
|
||||
int x = x1;
|
||||
|
||||
ColormapLight cmlight;
|
||||
cmlight.SetColormap(thread, MINZ, lightlevel, foggy, usecolormap, decal->RenderFlags & RF_FULLBRIGHT, false, false, false, false);
|
||||
|
||||
SpriteDrawerArgs drawerargs;
|
||||
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
else if (cameraLight->FixedColormap() != NULL)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
|
||||
else
|
||||
calclighting = true;
|
||||
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, basecolormap);
|
||||
|
||||
// R_SetPatchStyle can modify basecolormap.
|
||||
if (rereadcolormap)
|
||||
{
|
||||
usecolormap = basecolormap;
|
||||
}
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, cmlight);
|
||||
bool calclighting = cameraLight->FixedLightLevel() < 0 && !cameraLight->FixedColormap();
|
||||
|
||||
if (visible)
|
||||
{
|
||||
|
@ -318,7 +301,7 @@ namespace swrenderer
|
|||
{
|
||||
if (calclighting)
|
||||
{ // calculate lighting
|
||||
drawerargs.SetLight(usecolormap, light, lightlevel, foggy, thread->Viewport.get());
|
||||
drawerargs.SetLight(light, lightlevel, foggy, thread->Viewport.get());
|
||||
}
|
||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle);
|
||||
light += lightstep;
|
||||
|
|
|
@ -492,11 +492,7 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(Light.BaseColormap, 0, Light.ColormapNum << FRACBITS);
|
||||
|
||||
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(Light.BaseColormap);
|
||||
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), RenderStyle, Alpha, Translation, FillColor, basecolormap, Light.ColormapNum << FRACBITS);
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), RenderStyle, Alpha, Translation, FillColor, Light);
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
|
|
|
@ -323,12 +323,8 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(vis->Light.BaseColormap, 0, vis->Light.ColormapNum << FRACBITS);
|
||||
drawerargs.SetDynamicLight(dynlightcolor);
|
||||
|
||||
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(vis->Light.BaseColormap);
|
||||
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, basecolormap, vis->Light.ColormapNum << FRACBITS);
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, vis->Light);
|
||||
|
||||
if (visible)
|
||||
{
|
||||
|
|
|
@ -162,7 +162,6 @@ namespace swrenderer
|
|||
vis->Alpha = float(thing->Alpha);
|
||||
vis->fakefloor = fakefloor;
|
||||
vis->fakeceiling = fakeceiling;
|
||||
vis->Light.ColormapNum = 0;
|
||||
vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
|
||||
//vis->bSplitSprite = false;
|
||||
|
||||
|
@ -192,9 +191,7 @@ namespace swrenderer
|
|||
|
||||
// Fake a voxel drawing to find its extents..
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(vis->Light.BaseColormap, 0, vis->Light.ColormapNum << FRACBITS);
|
||||
basecolormap = (FDynamicColormap*)vis->Light.BaseColormap;
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, basecolormap);
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, vis->Light);
|
||||
if (!visible)
|
||||
return;
|
||||
int flags = vis->bInMirror ? (DVF_MIRRORED | DVF_FIND_X1X2) : DVF_FIND_X1X2;
|
||||
|
@ -211,10 +208,7 @@ namespace swrenderer
|
|||
auto viewport = thread->Viewport.get();
|
||||
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(spr->Light.BaseColormap, 0, spr->Light.ColormapNum << FRACBITS);
|
||||
|
||||
FDynamicColormap *basecolormap = (FDynamicColormap*)spr->Light.BaseColormap;
|
||||
bool visible = drawerargs.SetStyle(viewport, spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, basecolormap);
|
||||
bool visible = drawerargs.SetStyle(viewport, spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, spr->Light);
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
|
@ -908,12 +902,8 @@ namespace swrenderer
|
|||
auto sprite = this;
|
||||
auto viewport = RenderViewport::Instance();
|
||||
|
||||
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(sprite->Light.BaseColormap);
|
||||
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(sprite->Light.BaseColormap, 0, sprite->Light.ColormapNum << FRACBITS);
|
||||
|
||||
bool visible = drawerargs.SetStyle(sprite->RenderStyle, sprite->Alpha, sprite->Translation, sprite->FillColor, basecolormap);
|
||||
bool visible = drawerargs.SetStyle(sprite->RenderStyle, sprite->Alpha, sprite->Translation, sprite->FillColor, sprite->Light);
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
|
|
|
@ -176,32 +176,27 @@ namespace swrenderer
|
|||
walltexcoords.UPos[i] = right - walltexcoords.UPos[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare lighting
|
||||
bool calclighting = false;
|
||||
FSWColormap *usecolormap = spr->Light.BaseColormap;
|
||||
bool rereadcolormap = true;
|
||||
|
||||
// Decals that are added to the scene must fade to black.
|
||||
if (spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
||||
ColormapLight cmlight;
|
||||
if (spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && cmlight.BaseColormap->Fade != 0)
|
||||
{
|
||||
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
|
||||
rereadcolormap = false;
|
||||
cmlight.BaseColormap = GetSpecialLights(cmlight.BaseColormap->Color, 0, cmlight.BaseColormap->Desaturate);
|
||||
}
|
||||
|
||||
SpriteDrawerArgs drawerargs;
|
||||
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, cmlight);
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
float lightleft = float(thread->Light->WallVis(spr->wallc.sz1, foggy));
|
||||
float lightstep = float((thread->Light->WallVis(spr->wallc.sz2, foggy) - lightleft) / (spr->wallc.sx2 - spr->wallc.sx1));
|
||||
float light = lightleft + (x1 - spr->wallc.sx1) * lightstep;
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight(usecolormap, 0, cameraLight->FixedLightLevelShade());
|
||||
else if (cameraLight->FixedColormap() != NULL)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
else if (!spr->foggy && (spr->renderflags & RF_FULLBRIGHT))
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
|
||||
else
|
||||
calclighting = true;
|
||||
bool calclighting = cameraLight->FixedLightLevel() < 0 && !cameraLight->FixedColormap();
|
||||
|
||||
// Draw it
|
||||
auto WallSpriteTile = spr->pic;
|
||||
|
@ -220,36 +215,19 @@ namespace swrenderer
|
|||
|
||||
int x = x1;
|
||||
|
||||
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(spr->Light.BaseColormap);
|
||||
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
|
||||
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, basecolormap);
|
||||
|
||||
// R_SetPatchStyle can modify basecolormap.
|
||||
if (rereadcolormap)
|
||||
thread->PrepareTexture(WallSpriteTile, spr->RenderStyle);
|
||||
while (x < x2)
|
||||
{
|
||||
usecolormap = spr->Light.BaseColormap;
|
||||
}
|
||||
|
||||
if (!visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
|
||||
|
||||
thread->PrepareTexture(WallSpriteTile, spr->RenderStyle);
|
||||
while (x < x2)
|
||||
if (calclighting)
|
||||
{
|
||||
if (calclighting)
|
||||
{ // calculate lighting
|
||||
drawerargs.SetLight(usecolormap, light, spr->sector->lightlevel, spr->foggy, thread->Viewport.get());
|
||||
}
|
||||
if (!translucentPass->ClipSpriteColumnWithPortals(x, spr))
|
||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle);
|
||||
light += lightstep;
|
||||
x++;
|
||||
drawerargs.SetLight(light, spr->sector->lightlevel, spr->foggy, thread->Viewport.get());
|
||||
}
|
||||
if (!translucentPass->ClipSpriteColumnWithPortals(x, spr))
|
||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle);
|
||||
light += lightstep;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,15 +24,26 @@
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
void DrawerArgs::SetLight(FSWColormap *base_colormap, float light, int lightlevel, bool foggy, RenderViewport *viewport)
|
||||
{
|
||||
SetLight(base_colormap, light, LightVisibility::LightLevelToShade(lightlevel, foggy, viewport));
|
||||
}
|
||||
|
||||
void DrawerArgs::SetLight(FSWColormap *base_colormap, float light, int shade)
|
||||
void DrawerArgs::SetBaseColormap(FSWColormap *base_colormap)
|
||||
{
|
||||
mBaseColormap = base_colormap;
|
||||
assert(mBaseColormap->Maps != nullptr);
|
||||
}
|
||||
|
||||
void DrawerArgs::SetLight(float light, int lightlevel, bool foggy, RenderViewport *viewport)
|
||||
{
|
||||
mLight = light;
|
||||
mShade = LightVisibility::LightLevelToShade(lightlevel, foggy, viewport);
|
||||
}
|
||||
|
||||
void DrawerArgs::SetLight(const ColormapLight &light)
|
||||
{
|
||||
SetBaseColormap(light.BaseColormap);
|
||||
SetLight(0.0f, light.ColormapNum << FRACBITS);
|
||||
}
|
||||
|
||||
void DrawerArgs::SetLight(float light, int shade)
|
||||
{
|
||||
mLight = light;
|
||||
mShade = shade;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ struct FLightNode;
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
class ColormapLight;
|
||||
class SWPixelFormatDrawers;
|
||||
class DrawerArgs;
|
||||
struct ShadeConstants;
|
||||
|
@ -30,8 +31,9 @@ namespace swrenderer
|
|||
class DrawerArgs
|
||||
{
|
||||
public:
|
||||
void SetLight(FSWColormap *base_colormap, float light, int shade);
|
||||
void SetLight(FSWColormap *base_colormap, float light, int lightlevel, bool foggy, RenderViewport *viewport);
|
||||
void SetBaseColormap(FSWColormap *base_colormap);
|
||||
void SetLight(float light, int shade);
|
||||
void SetLight(float light, int lightlevel, bool foggy, RenderViewport *viewport);
|
||||
void SetTranslationMap(lighttable_t *translation);
|
||||
|
||||
uint8_t *Colormap(RenderViewport *viewport) const;
|
||||
|
@ -40,6 +42,9 @@ namespace swrenderer
|
|||
ShadeConstants ColormapConstants() const;
|
||||
fixed_t Light() const { return LIGHTSCALE(mLight, mShade); }
|
||||
|
||||
protected:
|
||||
void SetLight(const ColormapLight &light);
|
||||
|
||||
private:
|
||||
FSWColormap *mBaseColormap = nullptr;
|
||||
float mLight = 0.0f;
|
||||
|
|
|
@ -40,6 +40,21 @@ namespace swrenderer
|
|||
thread->Drawers(dc_viewport)->DrawDoubleSkyColumn(*this);
|
||||
}
|
||||
|
||||
void SkyDrawerArgs::SetStyle()
|
||||
{
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedColormap())
|
||||
{
|
||||
SetBaseColormap(cameraLight->FixedColormap());
|
||||
SetLight(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBaseColormap(&NormalLight);
|
||||
SetLight(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void SkyDrawerArgs::SetDest(RenderViewport *viewport, int x, int y)
|
||||
{
|
||||
dc_dest = viewport->GetDest(x, y);
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace swrenderer
|
|||
class SkyDrawerArgs : public DrawerArgs
|
||||
{
|
||||
public:
|
||||
void SetStyle();
|
||||
void SetDest(RenderViewport *viewport, int x, int y);
|
||||
void SetCount(int count) { dc_count = count; }
|
||||
void SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column);
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace swrenderer
|
|||
ds_source_mipmapped = tex->Mipmapped() && tex->GetPhysicalWidth() > 1 && tex->GetPhysicalHeight() > 1;
|
||||
}
|
||||
|
||||
void SpanDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha)
|
||||
void SpanDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha, FDynamicColormap *basecolormap)
|
||||
{
|
||||
if (masked)
|
||||
{
|
||||
|
@ -105,6 +105,22 @@ namespace swrenderer
|
|||
spanfunc = &SWPixelFormatDrawers::DrawSpan;
|
||||
}
|
||||
}
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
{
|
||||
SetBaseColormap((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap);
|
||||
SetLight(0, cameraLight->FixedLightLevelShade());
|
||||
}
|
||||
else if (cameraLight->FixedColormap())
|
||||
{
|
||||
SetBaseColormap(cameraLight->FixedColormap());
|
||||
SetLight(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBaseColormap(basecolormap);
|
||||
}
|
||||
}
|
||||
|
||||
void SpanDrawerArgs::DrawDepthSpan(RenderThread *thread, float idepth1, float idepth2)
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace swrenderer
|
|||
public:
|
||||
SpanDrawerArgs();
|
||||
|
||||
void SetStyle(bool masked, bool additive, fixed_t alpha);
|
||||
void SetStyle(bool masked, bool additive, fixed_t alpha, FDynamicColormap *basecolormap);
|
||||
void SetDestY(RenderViewport *viewport, int y) { ds_viewport = viewport; ds_y = y; }
|
||||
void SetDestX1(int x) { ds_x1 = x; }
|
||||
void SetDestX2(int x) { ds_x2 = x; }
|
||||
|
|
|
@ -382,8 +382,14 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
bool SpriteDrawerArgs::SetStyle(RenderViewport *viewport, FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade)
|
||||
bool SpriteDrawerArgs::SetStyle(RenderViewport *viewport, FRenderStyle style, fixed_t alpha, int translation, uint32_t color, const ColormapLight &light)
|
||||
{
|
||||
if (light.BaseColormap)
|
||||
SetLight(light);
|
||||
|
||||
FDynamicColormap *basecolormap = light.BaseColormap ? static_cast<FDynamicColormap*>(light.BaseColormap) : nullptr;
|
||||
fixed_t shadedlightshade = light.ColormapNum << FRACBITS;
|
||||
|
||||
fixed_t fglevel, bglevel;
|
||||
|
||||
drawer_needs_pal_input = false;
|
||||
|
@ -450,11 +456,13 @@ namespace swrenderer
|
|||
{
|
||||
fixed_t shade = shadedlightshade;
|
||||
if (shade == 0) shade = cameraLight->FixedLightLevelShade();
|
||||
SetLight(basecolormap, 0, shade);
|
||||
SetBaseColormap(basecolormap);
|
||||
SetLight(0, shade);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLight(basecolormap, 0, shadedlightshade);
|
||||
SetBaseColormap(basecolormap);
|
||||
SetLight(0, shadedlightshade);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -482,15 +490,16 @@ namespace swrenderer
|
|||
// dc_srccolor is used by the R_Fill* routines. It is premultiplied
|
||||
// with the alpha.
|
||||
dc_srccolor = ((((r*x) >> 4) << 20) | ((g*x) >> 4) | ((((b)*x) >> 4) << 10)) & 0x3feffbff;
|
||||
SetLight(&identitycolormap, 0, 0);
|
||||
SetBaseColormap(&identitycolormap);
|
||||
SetLight(0, 0);
|
||||
}
|
||||
|
||||
return SpriteDrawerArgs::SetBlendFunc(style.BlendOp, fglevel, bglevel, style.Flags);
|
||||
}
|
||||
|
||||
bool SpriteDrawerArgs::SetStyle(RenderViewport *viewport, FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade)
|
||||
bool SpriteDrawerArgs::SetStyle(RenderViewport *viewport, FRenderStyle style, float alpha, int translation, uint32_t color, const ColormapLight &light)
|
||||
{
|
||||
return SetStyle(viewport, style, FLOAT2FIXED(alpha), translation, color, basecolormap, shadedlightshade);
|
||||
return SetStyle(viewport, style, FLOAT2FIXED(alpha), translation, color, light);
|
||||
}
|
||||
|
||||
void SpriteDrawerArgs::FillColumn(RenderThread *thread)
|
||||
|
|
|
@ -26,8 +26,8 @@ namespace swrenderer
|
|||
public:
|
||||
SpriteDrawerArgs();
|
||||
|
||||
bool SetStyle(RenderViewport *viewport, FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade = 0);
|
||||
bool SetStyle(RenderViewport *viewport, FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade = 0);
|
||||
bool SetStyle(RenderViewport *viewport, FRenderStyle style, fixed_t alpha, int translation, uint32_t color, const ColormapLight &light);
|
||||
bool SetStyle(RenderViewport *viewport, FRenderStyle style, float alpha, int translation, uint32_t color, const ColormapLight &light);
|
||||
void SetDest(RenderViewport *viewport, int x, int y);
|
||||
void SetCount(int count) { dc_count = count; }
|
||||
void SetSolidColor(int color) { dc_color = color; dc_color_bgra = GPalette.BaseColors[color]; }
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace swrenderer
|
|||
(thread->Drawers(dc_viewport)->*wallfunc)(*this);
|
||||
}
|
||||
|
||||
void WallDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha)
|
||||
void WallDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha, FDynamicColormap *basecolormap)
|
||||
{
|
||||
if (alpha < OPAQUE || additive)
|
||||
{
|
||||
|
@ -71,10 +71,21 @@ namespace swrenderer
|
|||
{
|
||||
wallfunc = &SWPixelFormatDrawers::DrawWallColumn;
|
||||
}
|
||||
}
|
||||
|
||||
bool WallDrawerArgs::IsMaskedDrawer() const
|
||||
{
|
||||
return wallfunc == &SWPixelFormatDrawers::DrawWallMaskedColumn;
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
{
|
||||
SetBaseColormap((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap);
|
||||
SetLight(0.0f, cameraLight->FixedLightLevelShade());
|
||||
}
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
{
|
||||
SetBaseColormap(cameraLight->FixedColormap());
|
||||
SetLight(0.0f, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBaseColormap(basecolormap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace swrenderer
|
|||
class WallDrawerArgs : public DrawerArgs
|
||||
{
|
||||
public:
|
||||
void SetStyle(bool masked, bool additive, fixed_t alpha);
|
||||
void SetStyle(bool masked, bool additive, fixed_t alpha, FDynamicColormap *basecolormap);
|
||||
void SetDest(RenderViewport *viewport, int x, int y);
|
||||
void SetCount(int count) { dc_count = count; }
|
||||
void SetTexture(const uint8_t *pixels, const uint8_t *pixels2, int height)
|
||||
|
@ -28,8 +28,6 @@ namespace swrenderer
|
|||
void SetTextureVPos(fixed_t pos) { dc_texturefrac = pos; }
|
||||
void SetTextureVStep(fixed_t step) { dc_iscale = step; }
|
||||
|
||||
bool IsMaskedDrawer() const;
|
||||
|
||||
void DrawDepthColumn(RenderThread *thread, float idepth);
|
||||
void DrawColumn(RenderThread *thread);
|
||||
|
||||
|
|
|
@ -797,6 +797,7 @@ void FMultipatchTextureBuilder::CheckForHacks(BuildInfo &buildinfo)
|
|||
buildinfo.Height == 128)
|
||||
{
|
||||
buildinfo.Height = 200;
|
||||
buildinfo.tex->SetSize(buildinfo.tex->Width, 200);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -924,6 +925,7 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
|
|||
while (BuiltTextures.Size() > 0)
|
||||
{
|
||||
bool donesomething = false;
|
||||
|
||||
for (unsigned i = 0; i < BuiltTextures.Size(); i++)
|
||||
{
|
||||
auto &buildinfo = BuiltTextures[i];
|
||||
|
|
|
@ -298,7 +298,8 @@ class FTexture
|
|||
friend class FMultiPatchTexture;
|
||||
friend class FSkyBox;
|
||||
friend class FBrightmapTexture;
|
||||
friend class FFontChar1;
|
||||
friend class FFont;
|
||||
friend class FSpecialFont;
|
||||
friend void RecordTextureColors (FTexture *pic, uint8_t *usedcolors);
|
||||
|
||||
|
||||
|
@ -431,14 +432,11 @@ protected:
|
|||
float shaderspeed = 1.f;
|
||||
int shaderindex = 0;
|
||||
|
||||
// This is only legal for the null texture!
|
||||
// This is only used for the null texture and for Heretic's skies.
|
||||
void SetSize(int w, int h)
|
||||
{
|
||||
if (UseType == ETextureType::Null)
|
||||
{
|
||||
Width = w;
|
||||
Height = h;
|
||||
}
|
||||
Width = w;
|
||||
Height = h;
|
||||
}
|
||||
|
||||
void SetSpeed(float fac) { shaderspeed = fac; }
|
||||
|
@ -492,15 +490,6 @@ protected:
|
|||
|
||||
FTexture (const char *name = NULL, int lumpnum = -1);
|
||||
|
||||
void CopyInfo(FTexture *other)
|
||||
{
|
||||
CopySize(other);
|
||||
bNoDecals = other->bNoDecals;
|
||||
Rotations = other->Rotations;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
||||
bool GetTranslucency();
|
||||
|
|
|
@ -385,6 +385,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
{
|
||||
Chars[i].OriginalPic = charLumps[i];
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), "");
|
||||
Chars[i].TranslatedPic->Scale = charLumps[i]->Scale;
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
else Chars[i].TranslatedPic = charLumps[i];
|
||||
|
@ -1546,6 +1547,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
if (!noTranslate)
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), "");
|
||||
Chars[i].TranslatedPic->Scale = charlumps[i]->Scale;
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
else Chars[i].TranslatedPic = charlumps[i];
|
||||
|
|
|
@ -122,12 +122,12 @@ vec4 getTexel(vec2 st)
|
|||
// Vanilla Doom wall colormap equation
|
||||
//
|
||||
//===========================================================================
|
||||
float R_WallColormap(float lightnum, float z)
|
||||
float R_WallColormap(float lightnum, float z, vec3 normal)
|
||||
{
|
||||
// R_ScaleFromGlobalAngle calculation
|
||||
float projection = 160.0; // projection depends on SCREENBLOCKS!! 160 is the fullscreen value
|
||||
vec2 line_v1 = pixelpos.xz; // in vanilla this is the first curline vertex
|
||||
vec2 line_normal = vWorldNormal.xz;
|
||||
vec2 line_normal = normal.xz;
|
||||
float texscale = projection * clamp(dot(normalize(uCameraPos.xz - line_v1), line_normal), 0.0, 1.0) / z;
|
||||
|
||||
float lightz = clamp(16.0 * texscale, 0.0, 47.0);
|
||||
|
@ -174,7 +174,8 @@ float R_DoomColormap(float light, float z)
|
|||
|
||||
if (dot(vWorldNormal.xyz, vWorldNormal.xyz) > 0.5)
|
||||
{
|
||||
return mix(R_WallColormap(lightnum, z), R_PlaneColormap(lightnum, z), abs(vWorldNormal.y));
|
||||
vec3 normal = normalize(vWorldNormal.xyz);
|
||||
return mix(R_WallColormap(lightnum, z, normal), R_PlaneColormap(lightnum, z), abs(normal.y));
|
||||
}
|
||||
else // vWorldNormal is not set on sprites
|
||||
{
|
||||
|
|
|
@ -625,6 +625,9 @@ class Actor : Thinker native
|
|||
native clearscope Actor GetPointer(int aaptr);
|
||||
native double BulletSlope(out FTranslatedLineTarget pLineTarget = null, int aimflags = 0);
|
||||
native void CheckFakeFloorTriggers (double oldz, bool oldz_has_viewheight = false);
|
||||
native bool CheckFor3DFloorHit(double z, bool trigger);
|
||||
native bool CheckFor3DCeilingHit(double z, bool trigger);
|
||||
native int CheckMonsterUseSpecials();
|
||||
|
||||
native bool CheckMissileSpawn(double maxdist);
|
||||
native bool CheckPosition(Vector2 pos, bool actorsonly = false, FCheckPosition tm = null);
|
||||
|
@ -680,7 +683,7 @@ class Actor : Thinker native
|
|||
native void FindFloorCeiling(int flags = 0);
|
||||
native double, double GetFriction();
|
||||
native bool, Actor TestMobjZ(bool quick = false);
|
||||
native bool InStateSequence(State newstate, State basestate);
|
||||
native static bool InStateSequence(State newstate, State basestate);
|
||||
|
||||
bool TryWalk ()
|
||||
{
|
||||
|
|
|
@ -747,6 +747,7 @@ struct State native
|
|||
native int DistanceTo(state other);
|
||||
native bool ValidateSpriteFrame();
|
||||
native TextureID, bool, Vector2 GetSpriteTexture(int rotation, int skin = 0, Vector2 scale = (0,0));
|
||||
native bool InStateSequence(State base);
|
||||
}
|
||||
|
||||
struct F3DFloor native
|
||||
|
|
|
@ -811,24 +811,32 @@ class Weapon : StateProvider
|
|||
let player = Owner.player;
|
||||
if (SisterWeapon != NULL && bPowered_Up)
|
||||
{
|
||||
if (GetReadyState() != SisterWeapon.GetReadyState())
|
||||
let ready = GetReadyState();
|
||||
if (ready != SisterWeapon.GetReadyState())
|
||||
{
|
||||
if (player.PendingWeapon == NULL || player.PendingWeapon == WP_NOCHANGE)
|
||||
{
|
||||
player.PendingWeapon = SisterWeapon;
|
||||
}
|
||||
player.WeaponState |= WF_REFIRESWITCHOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
let psp = player.FindPSprite(PSP_WEAPON);
|
||||
if (psp != null && psp.Caller == player.ReadyWeapon)
|
||||
if (psp != null && psp.Caller == player.ReadyWeapon && psp.CurState.InStateSequence(ready))
|
||||
{
|
||||
// If the weapon changes but the state does not, we have to manually change the PSprite's caller here.
|
||||
psp.Caller = SisterWeapon;
|
||||
player.ReadyWeapon = SisterWeapon;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// Something went wrong. Initiate a regular weapon change.
|
||||
player.PendingWeapon = SisterWeapon;
|
||||
if (player.PendingWeapon == NULL || player.PendingWeapon == WP_NOCHANGE)
|
||||
{
|
||||
// Something went wrong. Initiate a regular weapon change.
|
||||
player.PendingWeapon = SisterWeapon;
|
||||
}
|
||||
player.WeaponState |= WF_REFIRESWITCHOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue