mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-19 07:31:03 +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;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ struct VersionInfo
|
|||
};
|
||||
|
||||
// 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 };
|
||||
}
|
||||
|
|
|
@ -484,6 +484,7 @@ void OpenGLFrameBuffer::SetSaveBuffers(bool yes)
|
|||
void OpenGLFrameBuffer::BeginFrame()
|
||||
{
|
||||
SetViewportRects(nullptr);
|
||||
mViewpoints->Clear();
|
||||
if (GLRenderer != nullptr)
|
||||
GLRenderer->BeginFrame();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@
|
|||
|
||||
static TArray<FString> m_Extensions;
|
||||
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
|
||||
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
|
||||
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);
|
||||
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()
|
||||
{
|
||||
// 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.
|
||||
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()
|
||||
{
|
||||
SetViewportRects(nullptr);
|
||||
mViewpoints->Clear();
|
||||
if (GLRenderer != nullptr)
|
||||
GLRenderer->BeginFrame();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
explicit OpenGLFrameBuffer() {}
|
||||
OpenGLFrameBuffer(void *hMonitor, bool fullscreen) ;
|
||||
~OpenGLFrameBuffer();
|
||||
int Backend() override { return 0; }
|
||||
|
||||
void InitializeState() 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(Int, gles_max_lights_per_surface, 32, 0);
|
||||
EXTERN_CVAR(Bool, gl_customshader);
|
||||
void setGlVersion(double glv);
|
||||
|
||||
|
||||
#if USE_GLES2
|
||||
|
@ -191,5 +192,9 @@ namespace OpenGLESRenderer
|
|||
#endif
|
||||
|
||||
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()
|
||||
{
|
||||
bool needNewPipeline = mUploadIndex > 0; // Clear might be called multiple times before any actual rendering
|
||||
|
||||
mUploadIndex = 0;
|
||||
mClipPlaneInfo.Clear();
|
||||
|
||||
mPipelinePos++;
|
||||
mPipelinePos %= mPipelineNbr;
|
||||
if (needNewPipeline)
|
||||
{
|
||||
mPipelinePos++;
|
||||
mPipelinePos %= mPipelineNbr;
|
||||
}
|
||||
|
||||
mBuffer = mBufferPipeline[mPipelinePos];
|
||||
}
|
||||
|
|
|
@ -419,6 +419,7 @@ TArray<uint8_t> VulkanFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo
|
|||
void VulkanFrameBuffer::BeginFrame()
|
||||
{
|
||||
SetViewportRects(nullptr);
|
||||
mViewpoints->Clear();
|
||||
mCommands->BeginFrame();
|
||||
mTextureManager->BeginFrame();
|
||||
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;
|
||||
}
|
||||
|
||||
FCompileContext::FCompileContext(PNamespace *cg, PContainerType *cls, bool fromdecorate)
|
||||
: ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0), Lump(-1), CurGlobals(cg)
|
||||
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), 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.)
|
||||
if (left->ValueType == TypeUInt32 && right->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())
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3324,6 +3346,59 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
@ -3929,7 +4004,7 @@ FxExpression *FxShift::Resolve(FCompileContext& ctx)
|
|||
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
@ -8233,7 +8308,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
member->membervar = newfield;
|
||||
Self = nullptr;
|
||||
delete this;
|
||||
member->ValueType = TypeUInt32;
|
||||
member->ValueType = TypeSInt32;
|
||||
return member;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -93,7 +93,7 @@ struct FCompileContext
|
|||
FString VersionString;
|
||||
|
||||
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 *FindInSelfClass(FName identifier, PSymbolTable *&symt);
|
||||
|
@ -910,7 +910,7 @@ public:
|
|||
|
||||
FxBinary(int, FxExpression*, FxExpression*);
|
||||
~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->RegType = REGT_FLOAT;
|
||||
TypeVector2->RegCount = 2;
|
||||
TypeVector2->isOrdered = true;
|
||||
|
||||
TypeVector3 = new PStruct(NAME_Vector3, nullptr);
|
||||
TypeVector3->AddField(NAME_X, TypeFloat64);
|
||||
|
@ -347,6 +348,7 @@ void PType::StaticInit()
|
|||
TypeVector3->moveOp = OP_MOVEV3;
|
||||
TypeVector3->RegType = REGT_FLOAT;
|
||||
TypeVector3->RegCount = 3;
|
||||
TypeVector3->isOrdered = true;
|
||||
|
||||
|
||||
TypeFVector2 = new PStruct(NAME_FVector2, nullptr);
|
||||
|
@ -358,6 +360,7 @@ void PType::StaticInit()
|
|||
TypeFVector2->moveOp = OP_MOVEV2;
|
||||
TypeFVector2->RegType = REGT_FLOAT;
|
||||
TypeFVector2->RegCount = 2;
|
||||
TypeFVector2->isOrdered = true;
|
||||
|
||||
TypeFVector3 = new PStruct(NAME_FVector3, nullptr);
|
||||
TypeFVector3->AddField(NAME_X, TypeFloat32);
|
||||
|
@ -371,6 +374,7 @@ void PType::StaticInit()
|
|||
TypeFVector3->moveOp = OP_MOVEV3;
|
||||
TypeFVector3->RegType = REGT_FLOAT;
|
||||
TypeFVector3->RegCount = 3;
|
||||
TypeFVector3->isOrdered = true;
|
||||
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_sByte, TypeSInt8));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Byte, TypeUInt8));
|
||||
|
|
|
@ -537,6 +537,7 @@ public:
|
|||
PStruct(FName name, PTypeBase *outer, bool isnative = false);
|
||||
|
||||
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.
|
||||
VMFunction *mConstructor = nullptr;
|
||||
VMFunction *mDestructor = nullptr;
|
||||
|
|
|
@ -68,7 +68,7 @@ const char * ZCCCompiler::GetStringConst(FxExpression *ex, FCompileContext &ctx)
|
|||
|
||||
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);
|
||||
ex = ex->Resolve(ctx);
|
||||
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)
|
||||
{
|
||||
FCompileContext ctx(OutNamespace, cls, false);
|
||||
FCompileContext ctx(OutNamespace, cls, false, mVersion);
|
||||
FxExpression *ex = new FxStringCast(ConvertNode(node));
|
||||
ex = ex->Resolve(ctx);
|
||||
if (ex == nullptr) return "";
|
||||
|
@ -1144,7 +1144,7 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant)
|
|||
|
||||
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);
|
||||
try
|
||||
{
|
||||
|
@ -1185,7 +1185,7 @@ void ZCCCompiler::CompileArrays(ZCC_StructWork *work)
|
|||
ConvertNodeList(values, sas->Values);
|
||||
|
||||
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);
|
||||
memset(destmem, 0, values.Size() * ztype->Align);
|
||||
|
@ -1325,7 +1325,7 @@ void ZCCCompiler::CompileAllFields()
|
|||
{
|
||||
// Create copies of the arrays which can be altered
|
||||
auto Classes = this->Classes;
|
||||
auto Structs = this->Structs;
|
||||
auto Structs = OrderStructs();
|
||||
TMap<FName, bool> HasNativeChildren;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 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
|
||||
|
@ -1937,7 +2014,7 @@ PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize,
|
|||
indices = std::move(fixedIndices);
|
||||
}
|
||||
|
||||
FCompileContext ctx(OutNamespace, cls, false);
|
||||
FCompileContext ctx(OutNamespace, cls, false, mVersion);
|
||||
for (auto index : indices)
|
||||
{
|
||||
// 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);
|
||||
FCompileContext ctx(OutNamespace, c->Type(), false);
|
||||
FCompileContext ctx(OutNamespace, c->Type(), false, mVersion);
|
||||
x = x->Resolve(ctx);
|
||||
|
||||
if (x != nullptr)
|
||||
|
@ -2731,7 +2808,14 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute)
|
|||
}
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -135,6 +135,9 @@ protected:
|
|||
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 *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);
|
||||
|
||||
|
|
|
@ -998,7 +998,7 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
|
|||
}
|
||||
|
||||
UnsafeExecutionScope scope(unsafe);
|
||||
C_DoCommand(cmd);
|
||||
AddCommandString(cmd);
|
||||
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.
|
||||
if (deltaang >= 512 - maxangdelta && deltaang <= 512 + maxangdelta)
|
||||
{
|
||||
// orthogonal lines do not check the actual position so that certain off-sector sprites get handled properly.
|
||||
// In Wanton Destruction's airplane level there's such a sprite assigned to the wrong sector.
|
||||
if (d.X == 0)
|
||||
if (!((tspr->ang) & 510))
|
||||
{
|
||||
double newdist = fabs(tx - wal.pos.X);
|
||||
if (newdist < maxorthdist)
|
||||
// orthogonal lines do not check the actual position so that certain off-sector sprites get handled properly.
|
||||
// In Wanton Destruction's airplane level there's such a sprite assigned to the wrong sector.
|
||||
if (d.X == 0)
|
||||
{
|
||||
maxorthdist = newdist;
|
||||
best = &wal;
|
||||
double newdist = fabs(tx - wal.pos.X);
|
||||
if (newdist < maxorthdist)
|
||||
{
|
||||
maxorthdist = newdist;
|
||||
best = &wal;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d.Y == 0)
|
||||
{
|
||||
double newdist = fabs(ty - wal.pos.Y);
|
||||
if (newdist < maxorthdist)
|
||||
else if (d.Y == 0)
|
||||
{
|
||||
maxorthdist = newdist;
|
||||
best = &wal;
|
||||
double newdist = fabs(ty - wal.pos.Y);
|
||||
if (newdist < maxorthdist)
|
||||
{
|
||||
maxorthdist = newdist;
|
||||
best = &wal;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -49,7 +49,7 @@ const char *GetVersionString();
|
|||
#define RC_PRODUCTVERSION2 VERSIONSTR
|
||||
// These are for content versioning.
|
||||
#define VER_MAJOR 4
|
||||
#define VER_MINOR 7
|
||||
#define VER_MINOR 9
|
||||
#define VER_REVISION 0
|
||||
|
||||
#define ENG_MAJOR 1
|
||||
|
|
Loading…
Reference in a new issue