mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-31 21:20:39 +00:00
- refined wall sprite check so that orthogonally aligned sprites are only aligned to orthogonal walls.
Here even the slightest deviation can create problems.
This commit is contained in:
parent
cac54d42e9
commit
7debab7ff4
17 changed files with 233 additions and 41 deletions
|
@ -12,19 +12,19 @@ struct VersionInfo
|
||||||
uint16_t minor;
|
uint16_t minor;
|
||||||
uint32_t revision;
|
uint32_t revision;
|
||||||
|
|
||||||
bool operator <=(const VersionInfo& o) const
|
constexpr bool operator <=(const VersionInfo& o) const
|
||||||
{
|
{
|
||||||
return o.major > this->major || (o.major == this->major && o.minor > this->minor) || (o.major == this->major && o.minor == this->minor && o.revision >= this->revision);
|
return o.major > this->major || (o.major == this->major && o.minor > this->minor) || (o.major == this->major && o.minor == this->minor && o.revision >= this->revision);
|
||||||
}
|
}
|
||||||
bool operator >=(const VersionInfo& o) const
|
constexpr bool operator >=(const VersionInfo& o) const
|
||||||
{
|
{
|
||||||
return o.major < this->major || (o.major == this->major && o.minor < this->minor) || (o.major == this->major && o.minor == this->minor && o.revision <= this->revision);
|
return o.major < this->major || (o.major == this->major && o.minor < this->minor) || (o.major == this->major && o.minor == this->minor && o.revision <= this->revision);
|
||||||
}
|
}
|
||||||
bool operator > (const VersionInfo& o) const
|
constexpr bool operator > (const VersionInfo& o) const
|
||||||
{
|
{
|
||||||
return o.major < this->major || (o.major == this->major && o.minor < this->minor) || (o.major == this->major && o.minor == this->minor && o.revision < this->revision);
|
return o.major < this->major || (o.major == this->major && o.minor < this->minor) || (o.major == this->major && o.minor == this->minor && o.revision < this->revision);
|
||||||
}
|
}
|
||||||
bool operator < (const VersionInfo& o) const
|
constexpr bool operator < (const VersionInfo& o) const
|
||||||
{
|
{
|
||||||
return o.major > this->major || (o.major == this->major && o.minor > this->minor) || (o.major == this->major && o.minor == this->minor && o.revision > this->revision);
|
return o.major > this->major || (o.major == this->major && o.minor > this->minor) || (o.major == this->major && o.minor == this->minor && o.revision > this->revision);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ struct VersionInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
// Cannot be a constructor because Lemon would puke on it.
|
// Cannot be a constructor because Lemon would puke on it.
|
||||||
inline VersionInfo MakeVersion(unsigned int ma, unsigned int mi, unsigned int re = 0)
|
constexpr VersionInfo MakeVersion(unsigned int ma, unsigned int mi, unsigned int re = 0)
|
||||||
{
|
{
|
||||||
return{ (uint16_t)ma, (uint16_t)mi, (uint32_t)re };
|
return{ (uint16_t)ma, (uint16_t)mi, (uint32_t)re };
|
||||||
}
|
}
|
||||||
|
|
|
@ -484,6 +484,7 @@ void OpenGLFrameBuffer::SetSaveBuffers(bool yes)
|
||||||
void OpenGLFrameBuffer::BeginFrame()
|
void OpenGLFrameBuffer::BeginFrame()
|
||||||
{
|
{
|
||||||
SetViewportRects(nullptr);
|
SetViewportRects(nullptr);
|
||||||
|
mViewpoints->Clear();
|
||||||
if (GLRenderer != nullptr)
|
if (GLRenderer != nullptr)
|
||||||
GLRenderer->BeginFrame();
|
GLRenderer->BeginFrame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,8 @@
|
||||||
|
|
||||||
static TArray<FString> m_Extensions;
|
static TArray<FString> m_Extensions;
|
||||||
RenderContext gl;
|
RenderContext gl;
|
||||||
static double realglversion; // this is public so the statistics code can access it.
|
static double realglversion;
|
||||||
|
static bool bindless;
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -156,7 +157,7 @@ void gl_LoadExtensions()
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (strstr(gl.vendorstring, "ATI Tech"))
|
if (strstr(gl.vendorstring, "ATI Tech"))
|
||||||
{
|
{
|
||||||
gl.flags |= RFL_NO_CLIP_PLANES; // gl_ClipDistance is horribly broken on ATI GL3 drivers for Windows. (TBD: Relegate to vintage build? Maybe after the next survey.)
|
gl.flags |= RFL_NO_CLIP_PLANES; // gl_ClipDistance is horribly broken on ATI GL3 drivers for Windows.
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
gl.glslversion = 3.31f; // Force GLSL down to 3.3.
|
gl.glslversion = 3.31f; // Force GLSL down to 3.3.
|
||||||
|
@ -201,6 +202,8 @@ void gl_LoadExtensions()
|
||||||
|
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl.max_texturesize);
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl.max_texturesize);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
bindless = CheckExtension("GL_ARB_bindless_texture");
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -247,9 +250,14 @@ void gl_PrintStartupLog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setGlVersion(double glv)
|
||||||
|
{
|
||||||
|
realglversion = glv;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<double, bool> gl_getInfo()
|
std::pair<double, bool> gl_getInfo()
|
||||||
{
|
{
|
||||||
// gl_ARB_bindless_texture is the closest we can get to determine Vulkan support from OpenGL.
|
// gl_ARB_bindless_texture is the closest we can get to determine Vulkan support from OpenGL.
|
||||||
// This isn't foolproof because Intel doesn't support it but for NVidia and AMD support of this extension means Vulkan support.
|
// This isn't foolproof because Intel doesn't support it but for NVidia and AMD support of this extension means Vulkan support.
|
||||||
return std::make_pair(realglversion, CheckExtension("GL_ARB_bindless_texture"));
|
return std::make_pair(realglversion, bindless);
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,6 +369,7 @@ void OpenGLFrameBuffer::WaitForCommands(bool finish)
|
||||||
void OpenGLFrameBuffer::BeginFrame()
|
void OpenGLFrameBuffer::BeginFrame()
|
||||||
{
|
{
|
||||||
SetViewportRects(nullptr);
|
SetViewportRects(nullptr);
|
||||||
|
mViewpoints->Clear();
|
||||||
if (GLRenderer != nullptr)
|
if (GLRenderer != nullptr)
|
||||||
GLRenderer->BeginFrame();
|
GLRenderer->BeginFrame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
explicit OpenGLFrameBuffer() {}
|
explicit OpenGLFrameBuffer() {}
|
||||||
OpenGLFrameBuffer(void *hMonitor, bool fullscreen) ;
|
OpenGLFrameBuffer(void *hMonitor, bool fullscreen) ;
|
||||||
~OpenGLFrameBuffer();
|
~OpenGLFrameBuffer();
|
||||||
|
int Backend() override { return 0; }
|
||||||
|
|
||||||
void InitializeState() override;
|
void InitializeState() override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
|
@ -9,6 +9,7 @@ CVAR(Bool, gles_use_mapped_buffer, false, 0);
|
||||||
CVAR(Bool, gles_force_glsl_v100, false, 0);
|
CVAR(Bool, gles_force_glsl_v100, false, 0);
|
||||||
CVAR(Int, gles_max_lights_per_surface, 32, 0);
|
CVAR(Int, gles_max_lights_per_surface, 32, 0);
|
||||||
EXTERN_CVAR(Bool, gl_customshader);
|
EXTERN_CVAR(Bool, gl_customshader);
|
||||||
|
void setGlVersion(double glv);
|
||||||
|
|
||||||
|
|
||||||
#if USE_GLES2
|
#if USE_GLES2
|
||||||
|
@ -191,5 +192,9 @@ namespace OpenGLESRenderer
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gles.numlightvectors = (gles.maxlights * LIGHT_VEC4_NUM);
|
gles.numlightvectors = (gles.maxlights * LIGHT_VEC4_NUM);
|
||||||
|
|
||||||
|
const char* glversion = (const char*)glGetString(GL_VERSION);
|
||||||
|
setGlVersion( strtod(glversion, NULL));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,11 +117,16 @@ int HWViewpointBuffer::SetViewpoint(FRenderState &di, HWViewpointUniforms *vp)
|
||||||
|
|
||||||
void HWViewpointBuffer::Clear()
|
void HWViewpointBuffer::Clear()
|
||||||
{
|
{
|
||||||
|
bool needNewPipeline = mUploadIndex > 0; // Clear might be called multiple times before any actual rendering
|
||||||
|
|
||||||
mUploadIndex = 0;
|
mUploadIndex = 0;
|
||||||
mClipPlaneInfo.Clear();
|
mClipPlaneInfo.Clear();
|
||||||
|
|
||||||
mPipelinePos++;
|
if (needNewPipeline)
|
||||||
mPipelinePos %= mPipelineNbr;
|
{
|
||||||
|
mPipelinePos++;
|
||||||
|
mPipelinePos %= mPipelineNbr;
|
||||||
|
}
|
||||||
|
|
||||||
mBuffer = mBufferPipeline[mPipelinePos];
|
mBuffer = mBufferPipeline[mPipelinePos];
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,6 +419,7 @@ TArray<uint8_t> VulkanFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo
|
||||||
void VulkanFrameBuffer::BeginFrame()
|
void VulkanFrameBuffer::BeginFrame()
|
||||||
{
|
{
|
||||||
SetViewportRects(nullptr);
|
SetViewportRects(nullptr);
|
||||||
|
mViewpoints->Clear();
|
||||||
mCommands->BeginFrame();
|
mCommands->BeginFrame();
|
||||||
mTextureManager->BeginFrame();
|
mTextureManager->BeginFrame();
|
||||||
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
|
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
|
||||||
|
|
|
@ -104,8 +104,8 @@ FCompileContext::FCompileContext(PNamespace *cg, PFunction *fnc, PPrototype *ret
|
||||||
if (fnc != nullptr) Class = fnc->OwningClass;
|
if (fnc != nullptr) Class = fnc->OwningClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
FCompileContext::FCompileContext(PNamespace *cg, PContainerType *cls, bool fromdecorate)
|
FCompileContext::FCompileContext(PNamespace *cg, PContainerType *cls, bool fromdecorate, const VersionInfo& info)
|
||||||
: ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0), Lump(-1), CurGlobals(cg)
|
: ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0), Lump(-1), CurGlobals(cg), Version(info)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2678,13 +2678,26 @@ FxBinary::~FxBinary()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool FxBinary::Promote(FCompileContext &ctx, bool forceint)
|
bool FxBinary::Promote(FCompileContext &ctx, bool forceint, bool shiftop)
|
||||||
{
|
{
|
||||||
// math operations of unsigned ints results in an unsigned int. (16 and 8 bit values never get here, they get promoted to regular ints elsewhere already.)
|
// math operations of unsigned ints results in an unsigned int. (16 and 8 bit values never get here, they get promoted to regular ints elsewhere already.)
|
||||||
if (left->ValueType == TypeUInt32 && right->ValueType == TypeUInt32)
|
if (left->ValueType == TypeUInt32 && right->ValueType == TypeUInt32)
|
||||||
{
|
{
|
||||||
ValueType = TypeUInt32;
|
ValueType = TypeUInt32;
|
||||||
}
|
}
|
||||||
|
// If one side is an unsigned 32-bit int and the other side is a signed 32-bit int, the signed side is implicitly converted to unsigned,
|
||||||
|
else if (!ctx.FromDecorate && left->ValueType == TypeUInt32 && right->ValueType == TypeSInt32 && !shiftop && ctx.Version >= MakeVersion(4, 9, 0))
|
||||||
|
{
|
||||||
|
right = new FxIntCast(right, false, false, true);
|
||||||
|
right = right->Resolve(ctx);
|
||||||
|
ValueType = TypeUInt32;
|
||||||
|
}
|
||||||
|
else if (!ctx.FromDecorate && left->ValueType == TypeSInt32 && right->ValueType == TypeUInt32 && !shiftop && ctx.Version >= MakeVersion(4, 9, 0))
|
||||||
|
{
|
||||||
|
left = new FxIntCast(left, false, false, true);
|
||||||
|
left = left->Resolve(ctx);
|
||||||
|
ValueType = TypeUInt32;
|
||||||
|
}
|
||||||
else if (left->IsInteger() && right->IsInteger())
|
else if (left->IsInteger() && right->IsInteger())
|
||||||
{
|
{
|
||||||
ValueType = TypeSInt32; // Addition and subtraction forces all integer-derived types to signed int.
|
ValueType = TypeSInt32; // Addition and subtraction forces all integer-derived types to signed int.
|
||||||
|
@ -2728,6 +2741,15 @@ bool FxBinary::Promote(FCompileContext &ctx, bool forceint)
|
||||||
delete this;
|
delete this;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shift operators are different: The left operand defines the type and the right operand must always be made unsigned
|
||||||
|
if (shiftop)
|
||||||
|
{
|
||||||
|
ValueType = left->ValueType == TypeUInt32 ? TypeUInt32 : TypeSInt32;
|
||||||
|
right = new FxIntCast(right, false, false, true);
|
||||||
|
right = right->Resolve(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3324,6 +3346,59 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
|
||||||
}
|
}
|
||||||
else if (left->IsNumeric() && right->IsNumeric())
|
else if (left->IsNumeric() && right->IsNumeric())
|
||||||
{
|
{
|
||||||
|
if (left->IsInteger() && right->IsInteger())
|
||||||
|
{
|
||||||
|
if (ctx.Version >= MakeVersion(4, 9, 0))
|
||||||
|
{
|
||||||
|
// We need to do more checks here to catch problem cases.
|
||||||
|
if (left->ValueType == TypeUInt32 && right->ValueType == TypeSInt32)
|
||||||
|
{
|
||||||
|
if (left->isConstant() && !right->isConstant())
|
||||||
|
{
|
||||||
|
auto val = static_cast<FxConstant*>(left)->GetValue().GetUInt();
|
||||||
|
if (val > INT_MAX)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Comparison of signed value with out of range unsigned constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (right->isConstant() && !left->isConstant())
|
||||||
|
{
|
||||||
|
auto val = static_cast<FxConstant*>(right)->GetValue().GetInt();
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Comparison of unsigned value with negative constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!left->isConstant() && !right->isConstant())
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Comparison between signed and unsigned value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (left->ValueType == TypeSInt32 && right->ValueType == TypeUInt32)
|
||||||
|
{
|
||||||
|
if (left->isConstant() && !right->isConstant())
|
||||||
|
{
|
||||||
|
auto val = static_cast<FxConstant*>(left)->GetValue().GetInt();
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Comparison of unsigned value with negative constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (right->isConstant() && !left->isConstant())
|
||||||
|
{
|
||||||
|
auto val = static_cast<FxConstant*>(right)->GetValue().GetUInt();
|
||||||
|
if (val > INT_MAX)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Comparison of signed value with out of range unsigned constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!left->isConstant() && !right->isConstant())
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Comparison between signed and unsigned value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Promote(ctx);
|
Promote(ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3929,7 +4004,7 @@ FxExpression *FxShift::Resolve(FCompileContext& ctx)
|
||||||
|
|
||||||
if (left->IsNumeric() && right->IsNumeric())
|
if (left->IsNumeric() && right->IsNumeric())
|
||||||
{
|
{
|
||||||
if (!Promote(ctx, true)) return nullptr;
|
if (!Promote(ctx, true, true)) return nullptr;
|
||||||
if ((left->ValueType == TypeUInt32 && ctx.Version >= MakeVersion(3, 7)) && Operator == TK_RShift) Operator = TK_URShift;
|
if ((left->ValueType == TypeUInt32 && ctx.Version >= MakeVersion(3, 7)) && Operator == TK_RShift) Operator = TK_URShift;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -8233,7 +8308,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
member->membervar = newfield;
|
member->membervar = newfield;
|
||||||
Self = nullptr;
|
Self = nullptr;
|
||||||
delete this;
|
delete this;
|
||||||
member->ValueType = TypeUInt32;
|
member->ValueType = TypeSInt32;
|
||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -93,7 +93,7 @@ struct FCompileContext
|
||||||
FString VersionString;
|
FString VersionString;
|
||||||
|
|
||||||
FCompileContext(PNamespace *spc, PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump, const VersionInfo &ver);
|
FCompileContext(PNamespace *spc, PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump, const VersionInfo &ver);
|
||||||
FCompileContext(PNamespace *spc, PContainerType *cls, bool fromdecorate); // only to be used to resolve constants!
|
FCompileContext(PNamespace *spc, PContainerType *cls, bool fromdecorate, const VersionInfo& ver); // only to be used to resolve constants!
|
||||||
|
|
||||||
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
|
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
|
||||||
PSymbol *FindInSelfClass(FName identifier, PSymbolTable *&symt);
|
PSymbol *FindInSelfClass(FName identifier, PSymbolTable *&symt);
|
||||||
|
@ -910,7 +910,7 @@ public:
|
||||||
|
|
||||||
FxBinary(int, FxExpression*, FxExpression*);
|
FxBinary(int, FxExpression*, FxExpression*);
|
||||||
~FxBinary();
|
~FxBinary();
|
||||||
bool Promote(FCompileContext &ctx, bool forceint = false);
|
bool Promote(FCompileContext &ctx, bool forceint = false, bool shiftop = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -334,6 +334,7 @@ void PType::StaticInit()
|
||||||
TypeVector2->moveOp = OP_MOVEV2;
|
TypeVector2->moveOp = OP_MOVEV2;
|
||||||
TypeVector2->RegType = REGT_FLOAT;
|
TypeVector2->RegType = REGT_FLOAT;
|
||||||
TypeVector2->RegCount = 2;
|
TypeVector2->RegCount = 2;
|
||||||
|
TypeVector2->isOrdered = true;
|
||||||
|
|
||||||
TypeVector3 = new PStruct(NAME_Vector3, nullptr);
|
TypeVector3 = new PStruct(NAME_Vector3, nullptr);
|
||||||
TypeVector3->AddField(NAME_X, TypeFloat64);
|
TypeVector3->AddField(NAME_X, TypeFloat64);
|
||||||
|
@ -347,6 +348,7 @@ void PType::StaticInit()
|
||||||
TypeVector3->moveOp = OP_MOVEV3;
|
TypeVector3->moveOp = OP_MOVEV3;
|
||||||
TypeVector3->RegType = REGT_FLOAT;
|
TypeVector3->RegType = REGT_FLOAT;
|
||||||
TypeVector3->RegCount = 3;
|
TypeVector3->RegCount = 3;
|
||||||
|
TypeVector3->isOrdered = true;
|
||||||
|
|
||||||
|
|
||||||
TypeFVector2 = new PStruct(NAME_FVector2, nullptr);
|
TypeFVector2 = new PStruct(NAME_FVector2, nullptr);
|
||||||
|
@ -358,6 +360,7 @@ void PType::StaticInit()
|
||||||
TypeFVector2->moveOp = OP_MOVEV2;
|
TypeFVector2->moveOp = OP_MOVEV2;
|
||||||
TypeFVector2->RegType = REGT_FLOAT;
|
TypeFVector2->RegType = REGT_FLOAT;
|
||||||
TypeFVector2->RegCount = 2;
|
TypeFVector2->RegCount = 2;
|
||||||
|
TypeFVector2->isOrdered = true;
|
||||||
|
|
||||||
TypeFVector3 = new PStruct(NAME_FVector3, nullptr);
|
TypeFVector3 = new PStruct(NAME_FVector3, nullptr);
|
||||||
TypeFVector3->AddField(NAME_X, TypeFloat32);
|
TypeFVector3->AddField(NAME_X, TypeFloat32);
|
||||||
|
@ -371,6 +374,7 @@ void PType::StaticInit()
|
||||||
TypeFVector3->moveOp = OP_MOVEV3;
|
TypeFVector3->moveOp = OP_MOVEV3;
|
||||||
TypeFVector3->RegType = REGT_FLOAT;
|
TypeFVector3->RegType = REGT_FLOAT;
|
||||||
TypeFVector3->RegCount = 3;
|
TypeFVector3->RegCount = 3;
|
||||||
|
TypeFVector3->isOrdered = true;
|
||||||
|
|
||||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_sByte, TypeSInt8));
|
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_sByte, TypeSInt8));
|
||||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Byte, TypeUInt8));
|
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Byte, TypeUInt8));
|
||||||
|
|
|
@ -537,6 +537,7 @@ public:
|
||||||
PStruct(FName name, PTypeBase *outer, bool isnative = false);
|
PStruct(FName name, PTypeBase *outer, bool isnative = false);
|
||||||
|
|
||||||
bool isNative;
|
bool isNative;
|
||||||
|
bool isOrdered = false;
|
||||||
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use these two functions for it.
|
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use these two functions for it.
|
||||||
VMFunction *mConstructor = nullptr;
|
VMFunction *mConstructor = nullptr;
|
||||||
VMFunction *mDestructor = nullptr;
|
VMFunction *mDestructor = nullptr;
|
||||||
|
|
|
@ -68,7 +68,7 @@ const char * ZCCCompiler::GetStringConst(FxExpression *ex, FCompileContext &ctx)
|
||||||
|
|
||||||
int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PContainerType *cls)
|
int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PContainerType *cls)
|
||||||
{
|
{
|
||||||
FCompileContext ctx(OutNamespace, cls, false);
|
FCompileContext ctx(OutNamespace, cls, false, mVersion);
|
||||||
FxExpression *ex = new FxIntCast(ConvertNode(node), false);
|
FxExpression *ex = new FxIntCast(ConvertNode(node), false);
|
||||||
ex = ex->Resolve(ctx);
|
ex = ex->Resolve(ctx);
|
||||||
if (ex == nullptr) return 0;
|
if (ex == nullptr) return 0;
|
||||||
|
@ -82,7 +82,7 @@ int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PContainerType *cls)
|
||||||
|
|
||||||
FString ZCCCompiler::StringConstFromNode(ZCC_TreeNode *node, PContainerType *cls)
|
FString ZCCCompiler::StringConstFromNode(ZCC_TreeNode *node, PContainerType *cls)
|
||||||
{
|
{
|
||||||
FCompileContext ctx(OutNamespace, cls, false);
|
FCompileContext ctx(OutNamespace, cls, false, mVersion);
|
||||||
FxExpression *ex = new FxStringCast(ConvertNode(node));
|
FxExpression *ex = new FxStringCast(ConvertNode(node));
|
||||||
ex = ex->Resolve(ctx);
|
ex = ex->Resolve(ctx);
|
||||||
if (ex == nullptr) return "";
|
if (ex == nullptr) return "";
|
||||||
|
@ -1144,7 +1144,7 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant)
|
||||||
|
|
||||||
bool ZCCCompiler::CompileConstant(ZCC_ConstantWork *work)
|
bool ZCCCompiler::CompileConstant(ZCC_ConstantWork *work)
|
||||||
{
|
{
|
||||||
FCompileContext ctx(OutNamespace, work->cls, false);
|
FCompileContext ctx(OutNamespace, work->cls, false, mVersion);
|
||||||
FxExpression *exp = ConvertNode(work->node->Value);
|
FxExpression *exp = ConvertNode(work->node->Value);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1185,7 +1185,7 @@ void ZCCCompiler::CompileArrays(ZCC_StructWork *work)
|
||||||
ConvertNodeList(values, sas->Values);
|
ConvertNodeList(values, sas->Values);
|
||||||
|
|
||||||
bool fail = false;
|
bool fail = false;
|
||||||
FCompileContext ctx(OutNamespace, work->Type(), false);
|
FCompileContext ctx(OutNamespace, work->Type(), false, mVersion);
|
||||||
|
|
||||||
char *destmem = (char *)ClassDataAllocator.Alloc(values.Size() * ztype->Align);
|
char *destmem = (char *)ClassDataAllocator.Alloc(values.Size() * ztype->Align);
|
||||||
memset(destmem, 0, values.Size() * ztype->Align);
|
memset(destmem, 0, values.Size() * ztype->Align);
|
||||||
|
@ -1325,7 +1325,7 @@ void ZCCCompiler::CompileAllFields()
|
||||||
{
|
{
|
||||||
// Create copies of the arrays which can be altered
|
// Create copies of the arrays which can be altered
|
||||||
auto Classes = this->Classes;
|
auto Classes = this->Classes;
|
||||||
auto Structs = this->Structs;
|
auto Structs = OrderStructs();
|
||||||
TMap<FName, bool> HasNativeChildren;
|
TMap<FName, bool> HasNativeChildren;
|
||||||
|
|
||||||
// first step: Look for native classes with native children.
|
// first step: Look for native classes with native children.
|
||||||
|
@ -1612,6 +1612,83 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *
|
||||||
return Fields.Size() == 0;
|
return Fields.Size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ZCCCompiler :: OrderStructs
|
||||||
|
//
|
||||||
|
// Order the Structs array so that the least-dependant structs come first
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
TArray<ZCC_StructWork *> ZCCCompiler::OrderStructs()
|
||||||
|
{
|
||||||
|
TArray<ZCC_StructWork *> new_order;
|
||||||
|
|
||||||
|
for (auto struct_def : Structs)
|
||||||
|
{
|
||||||
|
if (std::find(new_order.begin(), new_order.end(), struct_def) != new_order.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AddStruct(new_order, struct_def);
|
||||||
|
}
|
||||||
|
return new_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ZCCCompiler :: AddStruct
|
||||||
|
//
|
||||||
|
// Adds a struct to the Structs array, preceded by all its dependant structs
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void ZCCCompiler::AddStruct(TArray<ZCC_StructWork *> &new_order, ZCC_StructWork *my_def)
|
||||||
|
{
|
||||||
|
PStruct *my_type = static_cast<PStruct *>(my_def->Type());
|
||||||
|
if (my_type)
|
||||||
|
{
|
||||||
|
if (my_type->isOrdered)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my_type->isOrdered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all struct fields and add them before this one
|
||||||
|
for (const auto field : my_def->Fields)
|
||||||
|
{
|
||||||
|
PType *fieldtype = DetermineType(my_type, field, field->Names->Name, field->Type, true, true);
|
||||||
|
if (fieldtype->isStruct() && !static_cast<PStruct *>(fieldtype)->isOrdered)
|
||||||
|
{
|
||||||
|
AddStruct(new_order, StructTypeToWork(static_cast<PStruct *>(fieldtype)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_order.Push(my_def);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ZCCCompiler :: StructTypeToWork
|
||||||
|
//
|
||||||
|
// Find the ZCC_StructWork that corresponds to a PStruct
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
ZCC_StructWork *ZCCCompiler::StructTypeToWork(const PStruct *type) const
|
||||||
|
{
|
||||||
|
assert(type->isStruct());
|
||||||
|
for (auto &def : Structs)
|
||||||
|
{
|
||||||
|
if (def->Type() == type)
|
||||||
|
{
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(false && "Struct not found");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// ZCCCompiler :: FieldFlagsToString
|
// ZCCCompiler :: FieldFlagsToString
|
||||||
|
@ -1937,7 +2014,7 @@ PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize,
|
||||||
indices = std::move(fixedIndices);
|
indices = std::move(fixedIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
FCompileContext ctx(OutNamespace, cls, false);
|
FCompileContext ctx(OutNamespace, cls, false, mVersion);
|
||||||
for (auto index : indices)
|
for (auto index : indices)
|
||||||
{
|
{
|
||||||
// There is no float->int casting here.
|
// There is no float->int casting here.
|
||||||
|
@ -2270,7 +2347,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
|
|
||||||
|
|
||||||
FxExpression *x = new FxTypeCast(ConvertNode(p->Default), type, false);
|
FxExpression *x = new FxTypeCast(ConvertNode(p->Default), type, false);
|
||||||
FCompileContext ctx(OutNamespace, c->Type(), false);
|
FCompileContext ctx(OutNamespace, c->Type(), false, mVersion);
|
||||||
x = x->Resolve(ctx);
|
x = x->Resolve(ctx);
|
||||||
|
|
||||||
if (x != nullptr)
|
if (x != nullptr)
|
||||||
|
@ -2731,7 +2808,14 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute)
|
||||||
}
|
}
|
||||||
else if (cnst->Type->isInt())
|
else if (cnst->Type->isInt())
|
||||||
{
|
{
|
||||||
return new FxConstant(cnst->IntVal, *ast);
|
if (cnst->Type == TypeUInt32)
|
||||||
|
{
|
||||||
|
return new FxConstant((unsigned)cnst->IntVal, *ast);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new FxConstant(cnst->IntVal, *ast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (cnst->Type == TypeBool)
|
else if (cnst->Type == TypeBool)
|
||||||
{
|
{
|
||||||
|
|
|
@ -135,6 +135,9 @@ protected:
|
||||||
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
|
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
|
||||||
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls, bool *nosize);
|
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls, bool *nosize);
|
||||||
PType *ResolveUserType(ZCC_BasicType *type, PSymbolTable *sym, bool nativetype);
|
PType *ResolveUserType(ZCC_BasicType *type, PSymbolTable *sym, bool nativetype);
|
||||||
|
TArray<ZCC_StructWork *> OrderStructs();
|
||||||
|
void AddStruct(TArray<ZCC_StructWork *> &new_order, ZCC_StructWork *struct_def);
|
||||||
|
ZCC_StructWork *StructTypeToWork(const PStruct *type) const;
|
||||||
|
|
||||||
void CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool forclass);
|
void CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool forclass);
|
||||||
|
|
||||||
|
|
|
@ -998,7 +998,7 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
UnsafeExecutionScope scope(unsafe);
|
UnsafeExecutionScope scope(unsafe);
|
||||||
C_DoCommand(cmd);
|
AddCommandString(cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,24 +70,27 @@ static walltype* IsOnWall(tspritetype* tspr, int height, DVector2& outpos)
|
||||||
// angle of the sprite must either be the wall's normal or the negative wall's normal to be aligned.
|
// angle of the sprite must either be the wall's normal or the negative wall's normal to be aligned.
|
||||||
if (deltaang >= 512 - maxangdelta && deltaang <= 512 + maxangdelta)
|
if (deltaang >= 512 - maxangdelta && deltaang <= 512 + maxangdelta)
|
||||||
{
|
{
|
||||||
// orthogonal lines do not check the actual position so that certain off-sector sprites get handled properly.
|
if (!((tspr->ang) & 510))
|
||||||
// In Wanton Destruction's airplane level there's such a sprite assigned to the wrong sector.
|
|
||||||
if (d.X == 0)
|
|
||||||
{
|
{
|
||||||
double newdist = fabs(tx - wal.pos.X);
|
// orthogonal lines do not check the actual position so that certain off-sector sprites get handled properly.
|
||||||
if (newdist < maxorthdist)
|
// In Wanton Destruction's airplane level there's such a sprite assigned to the wrong sector.
|
||||||
|
if (d.X == 0)
|
||||||
{
|
{
|
||||||
maxorthdist = newdist;
|
double newdist = fabs(tx - wal.pos.X);
|
||||||
best = &wal;
|
if (newdist < maxorthdist)
|
||||||
|
{
|
||||||
|
maxorthdist = newdist;
|
||||||
|
best = &wal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (d.Y == 0)
|
||||||
else if (d.Y == 0)
|
|
||||||
{
|
|
||||||
double newdist = fabs(ty - wal.pos.Y);
|
|
||||||
if (newdist < maxorthdist)
|
|
||||||
{
|
{
|
||||||
maxorthdist = newdist;
|
double newdist = fabs(ty - wal.pos.Y);
|
||||||
best = &wal;
|
if (newdist < maxorthdist)
|
||||||
|
{
|
||||||
|
maxorthdist = newdist;
|
||||||
|
best = &wal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -49,7 +49,7 @@ const char *GetVersionString();
|
||||||
#define RC_PRODUCTVERSION2 VERSIONSTR
|
#define RC_PRODUCTVERSION2 VERSIONSTR
|
||||||
// These are for content versioning.
|
// These are for content versioning.
|
||||||
#define VER_MAJOR 4
|
#define VER_MAJOR 4
|
||||||
#define VER_MINOR 7
|
#define VER_MINOR 9
|
||||||
#define VER_REVISION 0
|
#define VER_REVISION 0
|
||||||
|
|
||||||
#define ENG_MAJOR 1
|
#define ENG_MAJOR 1
|
||||||
|
|
Loading…
Reference in a new issue