From b2a88c1abdb28e131af9ec68077553fef297ac47 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 5 Jul 2016 01:17:12 +0200 Subject: [PATCH 01/12] - fixed: mapthinghexen_t::flags needs to be unsigned. This is necessary so that an incorrectly set 0x8000 bit won't enable all high flags. --- src/doomdata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdata.h b/src/doomdata.h index 4e4976800a..f809f05eaf 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -334,7 +334,7 @@ struct mapthinghexen_t SWORD z; SWORD angle; SWORD type; - SWORD flags; + WORD flags; BYTE special; BYTE args[5]; }; From e401588f40e43ae6bca9c6f823c30edb3b5ad1e7 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 11 Jul 2016 01:17:45 -0400 Subject: [PATCH 02/12] - Set -stdlib=libc++ and disable inconsistent-missing-override warning with OS X Clang (the latter may be useful for recent versions of Clang in general, but I can't tell at the moment.) --- src/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 93a165fb1a..67b7dbb173 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -484,6 +484,9 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" ) set( CMAKE_CXX_FLAGS "-Wno-unused-result ${CMAKE_CXX_FLAGS}" ) endif() + if(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set( CMAKE_CXX_FLAGS "-Wno-inconsistent-missing-override ${CMAKE_CXX_FLAGS}" ) + endif() set( CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_C_FLAGS}" ) set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_CXX_FLAGS}" ) @@ -511,6 +514,12 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) endif () endif () + # With standard Apple tools -stdlib=libc++ needs to be specified in order to get + # C++11 support using SDKs 10.7 and 10.8. + if ( APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) + set( CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}" ) + endif () + # Remove extra warnings when using the official DirectX headers. # Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid, # which is a royal pain. The previous version I had been using was fine with them. From 1f2c8181bb7e869d16f912cfbcb3cd6702c65238 Mon Sep 17 00:00:00 2001 From: Blue-Shadow Date: Tue, 5 Jul 2016 16:15:39 +0300 Subject: [PATCH 03/12] Added IfWaterLevel SBARINFO command --- src/g_shared/sbarinfo_commands.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index a09c49303b..b4a011510b 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -3440,6 +3440,30 @@ class CommandIfInvulnerable : public SBarInfoNegatableFlowControl //////////////////////////////////////////////////////////////////////////////// +class CommandIfWaterLevel : public SBarInfoNegatableFlowControl +{ + public: + CommandIfWaterLevel(SBarInfo *script) : SBarInfoNegatableFlowControl(script) + { + } + + void ParseNegatable(FScanner &sc, bool fullScreenOffsets) + { + sc.MustGetToken(TK_IntConst); + value = sc.Number; + } + void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) + { + SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged); + + SetTruth(statusBar->CPlayer->mo->waterlevel >= value, block, statusBar); + } + protected: + int value; +}; + +//////////////////////////////////////////////////////////////////////////////// + static const char *SBarInfoCommandNames[] = { "drawimage", "drawnumber", "drawswitchableimage", @@ -3450,7 +3474,7 @@ static const char *SBarInfoCommandNames[] = "isselected", "usesammo", "usessecondaryammo", "hasweaponpiece", "inventorybarnotvisible", "weaponammo", "ininventory", "alpha", "ifhealth", - "ifinvulnerable", + "ifinvulnerable", "ifwaterlevel", NULL }; @@ -3464,7 +3488,7 @@ enum SBarInfoCommands SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO, SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE, SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH, - SBARINFO_IFINVULNERABLE, + SBARINFO_IFINVULNERABLE, SBARINFO_IFWATERLEVEL, }; SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc) @@ -3499,6 +3523,7 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc) case SBARINFO_ALPHA: return new CommandAlpha(script); case SBARINFO_IFHEALTH: return new CommandIfHealth(script); case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script); + case SBARINFO_IFWATERLEVEL: return new CommandIfWaterLevel(script); } sc.ScriptError("Unknown command '%s'.\n", sc.String); From 7d1dc46665e76697c6abc02acd9da8628f5809d5 Mon Sep 17 00:00:00 2001 From: subenji Date: Thu, 7 Jul 2016 15:46:54 +0100 Subject: [PATCH 04/12] Implemented fix discussed in http://forum.zdoom.org/viewtopic.php?f=2&t=52428 rearding UserVar corruption in savegames --- src/farchive.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/farchive.cpp b/src/farchive.cpp index fc3d75bbbb..6697fd5b72 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -728,13 +728,13 @@ void FArchive::WriteByte(BYTE val) void FArchive::WriteInt16(WORD val) { - WORD out = LittleShort(val); + WORD out = SWAP_WORD(val); m_File->Write(&out, 2); } void FArchive::WriteInt32(DWORD val) { - int out = LittleLong(val); + int out = SWAP_DWORD(val); m_File->Write(&out, 4); } From 371896b2ccc4cd1b71943e6dec59deda35ae6185 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Mon, 4 Jul 2016 02:19:52 +0200 Subject: [PATCH 05/12] Properly use the boolean type in expressions This fixes things like 'if (GetCVar(x))' not working --- src/thingdef/thingdef_exp.cpp | 4 +- src/thingdef/thingdef_exp.h | 33 +-- src/thingdef/thingdef_expression.cpp | 338 +++++++++++++-------------- 3 files changed, 189 insertions(+), 186 deletions(-) diff --git a/src/thingdef/thingdef_exp.cpp b/src/thingdef/thingdef_exp.cpp index ca812e2e5b..35932e0be1 100644 --- a/src/thingdef/thingdef_exp.cpp +++ b/src/thingdef/thingdef_exp.cpp @@ -331,11 +331,11 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls) } else if (sc.CheckToken(TK_True)) { - return new FxConstant(1, scpos); + return new FxConstant(true, scpos); } else if (sc.CheckToken(TK_False)) { - return new FxConstant(0, scpos); + return new FxConstant(false, scpos); } else if (sc.CheckToken(TK_IntConst)) { diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index ac6b7eda3c..58820ea153 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -203,7 +203,6 @@ protected: public: virtual ~FxExpression() {} virtual FxExpression *Resolve(FCompileContext &ctx); - FxExpression *ResolveAsBoolean(FCompileContext &ctx); virtual bool isConstant() const; virtual void RequestAddress(); @@ -280,6 +279,13 @@ class FxConstant : public FxExpression ExpVal value; public: + FxConstant(bool val, const FScriptPosition &pos) : FxExpression(pos) + { + ValueType = value.Type = TypeBool; + value.Int = val; + isresolved = true; + } + FxConstant(int val, const FScriptPosition &pos) : FxExpression(pos) { ValueType = value.Type = TypeSInt32; @@ -358,6 +364,19 @@ public: // //========================================================================== +class FxBoolCast : public FxExpression +{ + FxExpression *basex; + +public: + + FxBoolCast(FxExpression *x); + ~FxBoolCast(); + FxExpression *Resolve(FCompileContext&); + + ExpEmit Emit(VMFunctionBuilder *build); +}; + class FxIntCast : public FxExpression { FxExpression *basex; @@ -384,18 +403,6 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; -class FxCastStateToBool : public FxExpression -{ - FxExpression *basex; - -public: - FxCastStateToBool(FxExpression *x); - ~FxCastStateToBool(); - FxExpression *Resolve(FCompileContext&); - - ExpEmit Emit(VMFunctionBuilder *build); -}; - //========================================================================== // // FxSign diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 04410189a0..463156d7f7 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -177,38 +177,6 @@ FxExpression *FxExpression::Resolve(FCompileContext &ctx) return this; } - -//========================================================================== -// -// -// -//========================================================================== - -FxExpression *FxExpression::ResolveAsBoolean(FCompileContext &ctx) -{ - ///FIXME: Use an actual boolean type - FxExpression *x = Resolve(ctx); - if (x != NULL) - { - if (x->ValueType->GetRegType() == REGT_INT) - { - x->ValueType = TypeSInt32; - } - else if (x->ValueType == TypeState) - { - x = new FxCastStateToBool(x); - x = x->Resolve(ctx); - } - else - { - ScriptPosition.Message(MSG_ERROR, "Not an integral type"); - delete this; - return NULL; - } - } - return x; -} - //========================================================================== // // @@ -327,6 +295,104 @@ ExpEmit FxConstant::Emit(VMFunctionBuilder *build) // //========================================================================== +FxBoolCast::FxBoolCast(FxExpression *x) + : FxExpression(x->ScriptPosition) +{ + basex = x; + ValueType = TypeBool; +} + +//========================================================================== +// +// +// +//========================================================================== + +FxBoolCast::~FxBoolCast() +{ + SAFE_DELETE(basex); +} + +//========================================================================== +// +// +// +//========================================================================== + +FxExpression *FxBoolCast::Resolve(FCompileContext &ctx) +{ + CHECKRESOLVED(); + SAFE_RESOLVE(basex, ctx); + + if (basex->ValueType == TypeBool) + { + FxExpression *x = basex; + basex = nullptr; + delete this; + return x; + } + else if (basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER) + { + if (basex->isConstant()) + { + assert(basex->ValueType != TypeState && "We shouldn't be able to generate a constant state ref"); + + ExpVal constval = static_cast(basex)->GetValue(); + FxExpression *x = new FxConstant(constval.GetBool(), ScriptPosition); + delete this; + return x; + } + return this; + } + ScriptPosition.Message(MSG_ERROR, "Numeric type expected"); + delete this; + return nullptr; +} + +//========================================================================== +// +// +// +//========================================================================== + +ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build) +{ + ExpEmit from = basex->Emit(build); + assert(!from.Konst); + assert(basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER); + ExpEmit to(build, REGT_INT); + from.Free(build); + + // Preload result with 0. + build->Emit(OP_LI, to.RegNum, 0); + + // Check source against 0. + if (from.RegType == REGT_INT) + { + build->Emit(OP_EQ_R, 1, from.RegNum, to.RegNum); + } + else if (from.RegType == REGT_FLOAT) + { + build->Emit(OP_EQF_K, 1, from.RegNum, build->GetConstantFloat(0.)); + } + else if (from.RegNum == REGT_POINTER) + { + build->Emit(OP_EQA_K, 1, from.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC)); + } + build->Emit(OP_JMP, 1); + + // Reload result with 1 if the comparison fell through. + build->Emit(OP_LI, to.RegNum, 1); + + return to; +} + +//========================================================================== +// +// +// +//========================================================================== + FxIntCast::FxIntCast(FxExpression *x) : FxExpression(x->ScriptPosition) { @@ -504,67 +570,6 @@ ExpEmit FxFloatCast::Emit(VMFunctionBuilder *build) // //========================================================================== -FxCastStateToBool::FxCastStateToBool(FxExpression *x) -: FxExpression(x->ScriptPosition) -{ - basex = x; - ValueType = TypeSInt32; -} - -//========================================================================== -// -// -// -//========================================================================== - -FxCastStateToBool::~FxCastStateToBool() -{ - SAFE_DELETE(basex); -} - -//========================================================================== -// -// -// -//========================================================================== - -FxExpression *FxCastStateToBool::Resolve(FCompileContext &ctx) -{ - CHECKRESOLVED(); - SAFE_RESOLVE(basex, ctx); - - assert(basex->ValueType == TypeState); - assert(!basex->isConstant() && "We shouldn't be able to generate a constant state ref"); - return this; -} - -//========================================================================== -// -// -// -//========================================================================== - -ExpEmit FxCastStateToBool::Emit(VMFunctionBuilder *build) -{ - ExpEmit from = basex->Emit(build); - assert(from.RegType == REGT_POINTER); - from.Free(build); - ExpEmit to(build, REGT_INT); - - // If from is NULL, produce 0. Otherwise, produce 1. - build->Emit(OP_LI, to.RegNum, 0); - build->Emit(OP_EQA_K, 1, from.RegNum, build->GetConstantAddress(NULL, ATAG_GENERIC)); - build->Emit(OP_JMP, 1); - build->Emit(OP_LI, to.RegNum, 1); - return to; -} - -//========================================================================== -// -// -// -//========================================================================== - FxPlusSign::FxPlusSign(FxExpression *operand) : FxExpression(operand->ScriptPosition) { @@ -765,10 +770,9 @@ FxExpression *FxUnaryNotBitwise::Resolve(FCompileContext& ctx) ExpEmit FxUnaryNotBitwise::Emit(VMFunctionBuilder *build) { - assert(ValueType == Operand->ValueType); - assert(ValueType == TypeSInt32); + assert(Operand->ValueType->GetRegType() == REGT_INT); ExpEmit from = Operand->Emit(build); - assert(from.Konst == 0); + assert(!from.Konst); // Do it in-place. build->Emit(OP_NOT, from.RegNum, from.RegNum, 0); return from; @@ -806,33 +810,23 @@ FxUnaryNotBoolean::~FxUnaryNotBoolean() FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx) { CHECKRESOLVED(); - if (Operand) + SAFE_RESOLVE(Operand, ctx); + + if (Operand->ValueType != TypeBool) { - Operand = Operand->ResolveAsBoolean(ctx); - } - if (!Operand) - { - delete this; - return NULL; + Operand = new FxBoolCast(Operand); + SAFE_RESOLVE(Operand, ctx); } - if (Operand->IsNumeric() || Operand->IsPointer()) + if (Operand->isConstant()) { - if (Operand->isConstant()) - { - bool result = !static_cast(Operand)->GetValue().GetBool(); - FxExpression *e = new FxConstant(result, ScriptPosition); - delete this; - return e; - } - } - else - { - ScriptPosition.Message(MSG_ERROR, "Numeric type expected"); + bool result = !static_cast(Operand)->GetValue().GetBool(); + FxExpression *e = new FxConstant(result, ScriptPosition); delete this; - return NULL; + return e; } - ValueType = TypeSInt32; + + ValueType = TypeBool; return this; } @@ -844,32 +838,14 @@ FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx) ExpEmit FxUnaryNotBoolean::Emit(VMFunctionBuilder *build) { + assert(Operand->ValueType == ValueType); + assert(ValueType == TypeBool); ExpEmit from = Operand->Emit(build); assert(!from.Konst); - ExpEmit to(build, REGT_INT); - from.Free(build); - - // Preload result with 0. - build->Emit(OP_LI, to.RegNum, 0, 0); - - // Check source against 0. - if (from.RegType == REGT_INT) - { - build->Emit(OP_EQ_R, 0, from.RegNum, to.RegNum); - } - else if (from.RegType == REGT_FLOAT) - { - build->Emit(OP_EQF_K, 0, from.RegNum, build->GetConstantFloat(0)); - } - else if (from.RegNum == REGT_POINTER) - { - build->Emit(OP_EQA_K, 0, from.RegNum, build->GetConstantAddress(NULL, ATAG_GENERIC)); - } - build->Emit(OP_JMP, 1); - - // Reload result with 1 if the comparison fell through. - build->Emit(OP_LI, to.RegNum, 1); - return to; + // ~x & 1 + build->Emit(OP_NOT, from.RegNum, from.RegNum, 0); + build->Emit(OP_AND_RK, from.RegNum, from.RegNum, build->GetConstantInt(1)); + return from; } //========================================================================== @@ -914,6 +890,10 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric) return false; } + if (left->ValueType == TypeBool && right->ValueType == TypeBool) + { + ValueType = TypeBool; + } if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_INT) { ValueType = TypeSInt32; @@ -1276,7 +1256,7 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx) return e; } Promote(ctx); - ValueType = TypeSInt32; + ValueType = TypeBool; return this; } @@ -1327,7 +1307,7 @@ ExpEmit FxCompareRel::Emit(VMFunctionBuilder *build) op1.Free(build); } - // See FxUnaryNotBoolean for comments, since it's the same thing. + // See FxBoolCast for comments, since it's the same thing. build->Emit(OP_LI, to.RegNum, 0, 0); build->Emit(instr, check, op1.RegNum, op2.RegNum); build->Emit(OP_JMP, 1); @@ -1392,7 +1372,7 @@ FxExpression *FxCompareEq::Resolve(FCompileContext& ctx) return e; } Promote(ctx); - ValueType = TypeSInt32; + ValueType = TypeBool; return this; } @@ -1600,7 +1580,7 @@ FxBinaryLogical::FxBinaryLogical(int o, FxExpression *l, FxExpression *r) Operator=o; left=l; right=r; - ValueType = TypeSInt32; + ValueType = TypeBool; } //========================================================================== @@ -1624,16 +1604,22 @@ FxBinaryLogical::~FxBinaryLogical() FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) { CHECKRESOLVED(); - if (left) left = left->ResolveAsBoolean(ctx); - if (right) right = right->ResolveAsBoolean(ctx); - if (!left || !right) + RESOLVE(left, ctx); + RESOLVE(right, ctx); + ABORT(right && left); + + if (left->ValueType != TypeBool) { - delete this; - return NULL; + left = new FxBoolCast(left); + SAFE_RESOLVE(left, ctx); + } + if (right->ValueType != TypeBool) + { + right = new FxBoolCast(right); + SAFE_RESOLVE(right, ctx); } int b_left=-1, b_right=-1; - if (left->isConstant()) b_left = static_cast(left)->GetValue().GetBool(); if (right->isConstant()) b_right = static_cast(right)->GetValue().GetBool(); @@ -1643,13 +1629,13 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) { if (b_left==0 || b_right==0) { - FxExpression *x = new FxConstant(0, ScriptPosition); + FxExpression *x = new FxConstant(true, ScriptPosition); delete this; return x; } else if (b_left==1 && b_right==1) { - FxExpression *x = new FxConstant(1, ScriptPosition); + FxExpression *x = new FxConstant(false, ScriptPosition); delete this; return x; } @@ -1672,13 +1658,13 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) { if (b_left==1 || b_right==1) { - FxExpression *x = new FxConstant(1, ScriptPosition); + FxExpression *x = new FxConstant(true, ScriptPosition); delete this; return x; } if (b_left==0 && b_right==0) { - FxExpression *x = new FxConstant(0, ScriptPosition); + FxExpression *x = new FxConstant(false, ScriptPosition); delete this; return x; } @@ -1697,14 +1683,6 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) return x; } } - if (left->ValueType->GetRegType() != REGT_INT) - { - left = new FxIntCast(left); - } - if (right->ValueType->GetRegType() != REGT_INT) - { - right = new FxIntCast(right); - } return this; } @@ -1804,17 +1782,25 @@ FxConditional::~FxConditional() FxExpression *FxConditional::Resolve(FCompileContext& ctx) { CHECKRESOLVED(); - if (condition) condition = condition->ResolveAsBoolean(ctx); + RESOLVE(condition, ctx); RESOLVE(truex, ctx); RESOLVE(falsex, ctx); ABORT(condition && truex && falsex); - if (truex->ValueType->GetRegType() == REGT_INT && falsex->ValueType->GetRegType() == REGT_INT) + if (truex->ValueType == TypeBool && falsex->ValueType == TypeBool) + ValueType = TypeBool; + else if (truex->ValueType->GetRegType() == REGT_INT && falsex->ValueType->GetRegType() == REGT_INT) ValueType = TypeSInt32; else if (truex->IsNumeric() && falsex->IsNumeric()) ValueType = TypeFloat64; //else if (truex->ValueType != falsex->ValueType) + if (condition->ValueType != TypeBool) + { + condition = new FxBoolCast(condition); + SAFE_RESOLVE(condition, ctx); + } + if (condition->isConstant()) { ExpVal condval = static_cast(condition)->GetValue(); @@ -3735,23 +3721,32 @@ FxIfStatement::~FxIfStatement() FxExpression *FxIfStatement::Resolve(FCompileContext &ctx) { CHECKRESOLVED(); - if (WhenTrue == NULL && WhenFalse == NULL) + + if (WhenTrue == nullptr && WhenFalse == nullptr) { // We don't do anything either way, so disappear delete this; - return NULL; + return nullptr; } - Condition = Condition->ResolveAsBoolean(ctx); - ABORT(Condition); - if (WhenTrue != NULL) + + SAFE_RESOLVE(Condition, ctx); + + if (Condition->ValueType != TypeBool) + { + Condition = new FxBoolCast(Condition); + SAFE_RESOLVE(Condition, ctx); + } + + if (WhenTrue != nullptr) { WhenTrue = WhenTrue->Resolve(ctx); ABORT(WhenTrue); } - if (WhenFalse != NULL) + if (WhenFalse != nullptr) { WhenFalse = WhenFalse->Resolve(ctx); ABORT(WhenFalse); } + ValueType = TypeVoid; if (Condition->isConstant()) @@ -3766,6 +3761,7 @@ FxExpression *FxIfStatement::Resolve(FCompileContext &ctx) delete this; return e; } + return this; } From af53f5a825ae1fa1d3f109f54d4bb6e55fc5ce2b Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Wed, 6 Jul 2016 00:32:26 +0200 Subject: [PATCH 06/12] Properly use the boolean type in function declarations This will get rid of useless casts like 'if (isPointerEqual(x))' It will also allow for proper casting in parameters like using a state as a boolean which is allowed in if statements for example --- src/thingdef/thingdef_parse.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index e4488de45c..c979302775 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -77,7 +77,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c sc.MustGetString(); x = new FxConstant(FSoundID(sc.String), sc); } - else if (type == TypeSInt32 || type == TypeFloat64) + else if (type == TypeBool || type == TypeSInt32 || type == TypeFloat64) { x = ParseExpression (sc, cls, constant); if (constant && !x->isConstant()) @@ -85,8 +85,12 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c sc.ScriptMessage("Default parameter must be constant."); FScriptPosition::ErrorCounter++; } - // Do automatic coercion between ints and floats. - if (type == TypeSInt32) + // Do automatic coercion between bools, ints and floats. + if (type == TypeBool) + { + x = new FxBoolCast(x); + } + else if (type == TypeSInt32) { x = new FxIntCast(x); } @@ -306,6 +310,9 @@ static void ParseArgListDef(FScanner &sc, PClassActor *cls, switch (sc.TokenType) { case TK_Bool: + type = TypeBool; + break; + case TK_Int: type = TypeSInt32; break; @@ -477,8 +484,11 @@ static void ParseNativeFunction(FScanner &sc, PClassActor *cls) sc.MustGetAnyToken(); switch (sc.TokenType) { - case TK_Int: case TK_Bool: + rets.Push(TypeBool); + break; + + case TK_Int: rets.Push(TypeSInt32); break; @@ -1064,7 +1074,11 @@ static void ParseActionDef (FScanner &sc, PClassActor *cls) // check for a return value do { - if (sc.CheckToken(TK_Int) || sc.CheckToken(TK_Bool)) + if (sc.CheckToken(TK_Bool)) + { + rets.Push(TypeBool); + } + else if (sc.CheckToken(TK_Int)) { rets.Push(TypeSInt32); } From bbdc64a955eb3b438bb8dc6acc689fe5c49d1875 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 8 Jul 2016 18:39:18 +0200 Subject: [PATCH 07/12] Fixed bad serialization of float types The value was written twice if it couldn't be reduced to a single precision value --- src/dobjtype.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 6b963f6d4d..a7f07247f2 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -1272,6 +1272,7 @@ void PFloat::WriteValue(FArchive &ar, const void *addr) const { ar.WriteByte(VAL_Float64); ar << doubleprecision; + return; } } else From bdeb2338498840918cb581e8d1ab47235af3ca5c Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Mon, 4 Jul 2016 19:54:26 +0200 Subject: [PATCH 08/12] Fixed: conditionals didn't properly compile to vm code --- src/thingdef/thingdef_expression.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 463156d7f7..b4a0b3fda1 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -1838,6 +1838,7 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx) ExpEmit FxConditional::Emit(VMFunctionBuilder *build) { + size_t truejump, falsejump; ExpEmit out; // The true and false expressions ought to be assigned to the @@ -1848,7 +1849,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build) // Test condition. build->Emit(OP_EQ_K, 1, cond.RegNum, build->GetConstantInt(0)); - size_t patchspot = build->Emit(OP_JMP, 0); + falsejump = build->Emit(OP_JMP, 0); // Evaluate true expression. if (truex->isConstant() && truex->ValueType->GetRegType() == REGT_INT) @@ -1872,9 +1873,11 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build) out = trueop; } } + // Make sure to skip the false path. + truejump = build->Emit(OP_JMP, 0); // Evaluate false expression. - build->BackpatchToHere(patchspot); + build->BackpatchToHere(falsejump); if (falsex->isConstant() && falsex->ValueType->GetRegType() == REGT_INT) { build->EmitLoadInt(out.RegNum, static_cast(falsex)->GetValue().GetInt()); @@ -1904,6 +1907,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build) } } } + build->BackpatchToHere(truejump); return out; } From 79264cb8cd5a08d852a45b57f016cd672fd3f174 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 12 Jul 2016 19:57:32 +0200 Subject: [PATCH 09/12] - fixed missing QuakeEx parameter conversion. --- src/p_acs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 7cbfd69b48..919834a067 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5712,8 +5712,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) argCount > 11 ? ACSToDouble(args[11]) : 1.0, argCount > 12 ? args[12] : 0, argCount > 13 ? args[13] : 0, - argCount > 14 ? args[14] : 0, - argCount > 15 ? args[15] : 0); + argCount > 14 ? ACSToDouble(args[14]) : 0, + argCount > 15 ? ACSToDouble(args[15]) : 0); } case ACSF_SetLineActivation: From 522b2f4706a8a67b40ebc2f1e4332b3257faf7ae Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 12 Jul 2016 23:50:45 +0200 Subject: [PATCH 10/12] - updated xlat/eternity.txt for reference. --- wadsrc/static/xlat/eternity.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/wadsrc/static/xlat/eternity.txt b/wadsrc/static/xlat/eternity.txt index bc5159d11b..4db96f2da5 100644 --- a/wadsrc/static/xlat/eternity.txt +++ b/wadsrc/static/xlat/eternity.txt @@ -234,3 +234,20 @@ enum 447 = 0, Exit_Normal(0) 448 = 0, Exit_Secret(0) 449 = 0, Teleport_NewMap(0) +450 = 0, Line_Horizon(0) +451 = 0, Floor_RaiseAndCrush(0) +452 = 0, Floor_CrushStop(0) +453 = 0, FloorAndCeiling_LowerByValue(0) +454 = 0, FloorAndCeiling_RaiseByValue(0) +457 = 0, Door_LockedOpen(0) +458 = 0, Elevator_RaiseToNearest(0) +459 = 0, Elevator_LowerToNearest(0) +460 = 0, Elevator_MoveToFloor(0) +461 = 0, Light_MaxNeighbor(0) +462 = 0, ChangeSkill(0) +463 = 0, Light_StrobeDoom(0) +464 = 0, Generic_Floor(0) +465 = 0, Generic_Ceiling(0) +466 = 0, Floor_TransferTrigger(0) +467 = 0, Floor_TransferNumeric(0) +468 = 0, FloorAndCeiling_LowerRaise(0) From 1cf51791de7aec5d0555a65a01c4051164ef3646 Mon Sep 17 00:00:00 2001 From: m-x-d Date: Wed, 13 Jul 2016 00:27:59 +0300 Subject: [PATCH 11/12] Adds //%Title property to all locks to make parsing LOCKDEFS by map editors more feasible. Fixes: Strife Base key Message now uses LANGUAGE string. --- wadsrc/static/lockdefs.txt | 74 +++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/lockdefs.txt b/wadsrc/static/lockdefs.txt index 2167f935d8..04e4902244 100644 --- a/wadsrc/static/lockdefs.txt +++ b/wadsrc/static/lockdefs.txt @@ -5,6 +5,7 @@ ClearLocks Lock 1 Doom { + //$Title "Red key card" RedCard Message "$PD_REDC" RemoteMessage "$PD_REDCO" @@ -14,6 +15,7 @@ Lock 1 Doom Lock 2 Doom { + //$Title "Blue key card" BlueCard Message "$PD_BLUEC" RemoteMessage "$PD_BLUECO" @@ -23,6 +25,7 @@ Lock 2 Doom Lock 3 Doom { + //$Title "Yellow key card" YellowCard Message "$PD_YELLOWC" RemoteMessage "$PD_YELLOWCO" @@ -32,6 +35,7 @@ Lock 3 Doom Lock 4 Doom { + //$Title "Red skull" RedSkull Message "$PD_REDS" RemoteMessage "$PD_REDSO" @@ -41,6 +45,7 @@ Lock 4 Doom Lock 5 Doom { + //$Title "Blue skull" BlueSkull Message "$PD_BLUES" RemoteMessage "$PD_BLUESO" @@ -50,6 +55,7 @@ Lock 5 Doom Lock 6 Doom { + //$Title "Yellow skull" YellowSkull Message "$PD_YELLOWS" RemoteMessage "$PD_YELLOWSO" @@ -59,6 +65,7 @@ Lock 6 Doom Lock 129 Doom { + //$Title "Any red key" Any { RedCard RedSkull KeyGreen } Message "$PD_REDK" RemoteMessage "$PD_REDO" @@ -68,6 +75,7 @@ Lock 129 Doom Lock 130 Doom { + //$Title "Any blue key" Any { BlueCard BlueSkull KeyBlue } Message "$PD_BLUEK" RemoteMessage "$PD_BLUEO" @@ -77,6 +85,7 @@ Lock 130 Doom Lock 131 Doom { + //$Title "Any yellow key" Any { YellowCard YellowSkull KeyYellow } Message "$PD_YELLOWK" RemoteMessage "$PD_YELLOWO" @@ -86,6 +95,7 @@ Lock 131 Doom Lock 132 Doom { + //$Title "Red card or skull" Any { RedCard RedSkull } Message "$PD_REDK" RemoteMessage "$PD_REDO" @@ -95,6 +105,7 @@ Lock 132 Doom Lock 133 Doom { + //$Title "Blue card or skull" Any { BlueCard BlueSkull } Message "$PD_BLUEK" RemoteMessage "$PD_BLUEO" @@ -104,6 +115,7 @@ Lock 133 Doom Lock 134 Doom { + //$Title "Yellow card or skull" Any { YellowCard YellowSkull } Message "$PD_YELLOWK" RemoteMessage "$PD_YELLOWO" @@ -112,6 +124,7 @@ Lock 134 Doom Lock 100 { + //$Title "Any key" Message "$PD_ANY" RemoteMessage "$PD_ANYOBJ" Mapcolor 128 128 255 @@ -119,6 +132,7 @@ Lock 100 Lock 228 { + //$Title "Any key" Message "$PD_ANY" RemoteMessage "$PD_ANYOBJ" Mapcolor 128 128 255 @@ -126,6 +140,7 @@ Lock 228 Lock 229 Doom { + //$Title "One of each color" Any { BlueCard BlueSkull KeyBlue} Any { YellowCard YellowSkull KeyYellow} Any { RedCard RedSkull KeyGreen} @@ -135,6 +150,7 @@ Lock 229 Doom Lock 101 Doom { + //$Title "All keys" BlueCard BlueSkull YellowCard @@ -151,6 +167,7 @@ Lock 101 Doom Lock 1 Heretic { + //$Title "Green key" KeyGreen Message "$TXT_NEEDGREENKEY" Mapcolor 0 255 0 @@ -159,6 +176,7 @@ Lock 1 Heretic Lock 2 Heretic { + //$Title "Blue key" KeyBlue Message "$TXT_NEEDBLUEKEY" Mapcolor 0 0 255 @@ -167,6 +185,7 @@ Lock 2 Heretic Lock 3 Heretic { + //$Title "Yellow key" KeyYellow Message "$TXT_NEEDYELLOWKEY" Mapcolor 255 255 0 @@ -175,6 +194,7 @@ Lock 3 Heretic Lock 129 Heretic { + //$Title "Green key" KeyGreen Message "$TXT_NEEDGREENKEY" Mapcolor 0 255 0 @@ -183,6 +203,7 @@ Lock 129 Heretic Lock 130 Heretic { + //$Title "Blue key" KeyBlue Message "$TXT_NEEDBLUEKEY" Mapcolor 0 0 255 @@ -191,6 +212,7 @@ Lock 130 Heretic Lock 131 Heretic { + //$Title "Yellow key" KeyYellow Message "$TXT_NEEDYELLOWKEY" Mapcolor 255 255 0 @@ -199,6 +221,7 @@ Lock 131 Heretic Lock 229 Heretic { + //$Title "All keys" KeyGreen KeyYellow KeyBlue @@ -208,6 +231,7 @@ Lock 229 Heretic Lock 101 Heretic { + //$Title "All keys" KeyGreen KeyYellow KeyBlue @@ -222,6 +246,7 @@ Lock 101 Heretic Lock 1 Hexen { + //$Title "Steel key" KeySteel Message "$TXT_NEED_KEY_STEEL" Mapcolor 150 150 150 @@ -230,6 +255,7 @@ Lock 1 Hexen Lock 2 Hexen { + //$Title "Cave key" KeyCave Message "$TXT_NEED_KEY_CAVE" Mapcolor 255 218 0 @@ -238,6 +264,7 @@ Lock 2 Hexen Lock 3 Hexen { + //$Title "Axe key" KeyAxe Message "$TXT_NEED_KEY_AXE" Mapcolor 64 64 255 @@ -246,6 +273,7 @@ Lock 3 Hexen Lock 4 Hexen { + //$Title "Fire key" KeyFire Message "$TXT_NEED_KEY_FIRE" Mapcolor 255 128 0 @@ -254,6 +282,7 @@ Lock 4 Hexen Lock 5 Hexen { + //$Title "Emerald key" KeyEmerald Message "$TXT_NEED_KEY_EMERALD" Mapcolor 0 255 0 @@ -262,6 +291,7 @@ Lock 5 Hexen Lock 6 Hexen { + //$Title "Dungeon key" KeyDungeon Message "$TXT_NEED_KEY_DUNGEON" Mapcolor 47 151 255 @@ -270,6 +300,7 @@ Lock 6 Hexen Lock 7 Hexen { + //$Title "Silver key" KeySilver Message "$TXT_NEED_KEY_SILVER" Mapcolor 154 152 188 @@ -278,6 +309,7 @@ Lock 7 Hexen Lock 8 Hexen { + //$Title "Rusted key" KeyRusted Message "$TXT_NEED_KEY_RUSTED" Mapcolor 156 76 0 @@ -286,6 +318,7 @@ Lock 8 Hexen Lock 9 Hexen { + //$Title "Horn key" KeyHorn Message "$TXT_NEED_KEY_HORN" Mapcolor 255 218 0 @@ -294,6 +327,7 @@ Lock 9 Hexen Lock 10 Hexen { + //$Title "Swamp key" KeySwamp Message "$TXT_NEED_KEY_SWAMP" Mapcolor 64 255 64 @@ -302,6 +336,7 @@ Lock 10 Hexen Lock 11 Hexen { + //$Title "Castle key" KeyCastle Message "$TXT_NEED_KEY_CASTLE" Mapcolor 255 64 64 @@ -310,6 +345,7 @@ Lock 11 Hexen Lock 101 Hexen { + //$Title "All keys" KeySteel KeyCave KeyAxe @@ -326,6 +362,7 @@ Lock 101 Hexen Lock 229 Hexen { + //$Title "All keys" KeySteel KeyCave KeyAxe @@ -345,14 +382,16 @@ Lock 229 Hexen Lock 1 Strife { + //$Title "Base key" BaseKey - Message "You don't have the key" + Message "$TXT_NEEDKEY" Mapcolor 150 150 150 } Lock 2 Strife { + //$Title "Governor's key" GovsKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -361,6 +400,7 @@ Lock 2 Strife Lock 3 Strife { + //$Title "Travel passcard" Passcard RemoteMessage "$TXT_NEED_PASSCARD" Message "$TXT_NEED_PASSCARD_DOOR" @@ -370,6 +410,7 @@ Lock 3 Strife Lock 4 Strife { + //$Title "ID badge" IDBadge Message "$TXT_NEED_IDCARD" Mapcolor 255 128 0 @@ -378,6 +419,7 @@ Lock 4 Strife Lock 5 Strife { + //$Title "Prison key" PrisonKey Message "$TXT_NEED_PRISONKEY" Mapcolor 0 255 0 @@ -386,6 +428,7 @@ Lock 5 Strife Lock 6 Strife { + //$Title "Severed hand" SeveredHand Message "$TXT_NEED_HANDPRINT" Mapcolor 255 151 100 @@ -394,6 +437,7 @@ Lock 6 Strife Lock 7 Strife { + //$Title "Power key 1" Power1Key Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -402,6 +446,7 @@ Lock 7 Strife Lock 8 Strife { + //$Title "Power key 2" Power2Key Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -410,6 +455,7 @@ Lock 8 Strife Lock 9 Strife { + //$Title "Power key 3" Power3Key Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -418,6 +464,7 @@ Lock 9 Strife Lock 10 Strife { + //$Title "Gold key" GoldKey Message "$TXT_NEED_GOLDKEY" Mapcolor 255 200 0 @@ -426,6 +473,7 @@ Lock 10 Strife Lock 11 Strife { + //$Title "ID card" IDCard RemoteMessage "$TXT_NEED_IDBADGE" Message "$TXT_NEED_IDBADGE_DOOR" @@ -434,6 +482,7 @@ Lock 11 Strife Lock 12 Strife { + //$Title "Silver key" SilverKey Message "$TXT_NEED_SILVERKEY" Mapcolor 150 150 150 @@ -441,6 +490,7 @@ Lock 12 Strife Lock 13 Strife { + //$Title "Oracle key" OracleKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -448,6 +498,7 @@ Lock 13 Strife Lock 14 Strife { + //$Title "Military key" MilitaryID Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -455,6 +506,7 @@ Lock 14 Strife Lock 15 Strife { + //$Title "Order key" OrderKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -462,6 +514,7 @@ Lock 15 Strife Lock 16 Strife { + //$Title "Warehouse key" WarehouseKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -469,6 +522,7 @@ Lock 16 Strife Lock 17 Strife { + //$Title "Brass key" BrassKey Message "$TXT_NEED_BRASSKEY" Mapcolor 150 75 0 @@ -476,6 +530,7 @@ Lock 17 Strife Lock 18 Strife { + //$Title "Red crystal key" RedCrystalKey Message "$TXT_NEED_REDCRYSTAL" Mapcolor 150 150 150 @@ -483,6 +538,7 @@ Lock 18 Strife Lock 19 Strife { + //$Title "Blue crystal key" BlueCrystalKey Message "$TXT_NEED_BLUECRYSTAL" Mapcolor 150 150 150 @@ -490,6 +546,7 @@ Lock 19 Strife Lock 20 Strife { + //$Title "Chapel key" ChapelKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -497,6 +554,7 @@ Lock 20 Strife Lock 21 Strife { + //$Title "Catacomb key" CatacombKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -504,6 +562,7 @@ Lock 21 Strife Lock 22 Strife { + //$Title "Security key" SecurityKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -511,6 +570,7 @@ Lock 22 Strife Lock 23 Strife { + //$Title "Core key" CoreKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -518,6 +578,7 @@ Lock 23 Strife Lock 24 Strife { + //$Title "Mauler key" MaulerKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -525,6 +586,7 @@ Lock 24 Strife Lock 25 Strife { + //$Title "Factory key" FactoryKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -532,6 +594,7 @@ Lock 25 Strife Lock 26 Strife { + //$Title "Mine key" MineKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -539,6 +602,7 @@ Lock 26 Strife Lock 27 Strife { + //$Title "New key 5" NewKey5 Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -546,6 +610,7 @@ Lock 27 Strife Lock 50 Strife { + //$Title "Prison key" PrisonPass Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -553,6 +618,7 @@ Lock 50 Strife Lock 51 Strife { + //$Title "Oracle pass" OraclePass Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -564,6 +630,7 @@ Lock 51 Strife Lock 1 Chex { + //$Title "Red key card" ChexRedCard Message "$PD_REDC" RemoteMessage "$PD_REDCO" @@ -573,6 +640,7 @@ Lock 1 Chex Lock 2 Chex { + //$Title "Blue key card" ChexBlueCard Message "$PD_BLUEC" RemoteMessage "$PD_BLUECO" @@ -582,6 +650,7 @@ Lock 2 Chex Lock 3 Chex { + //$Title "Yellow key card" ChexYellowCard Message "$PD_YELLOWC" RemoteMessage "$PD_YELLOWCO" @@ -590,6 +659,7 @@ Lock 3 Chex Lock 129 Chex { + //$Title "Red key" ChexRedCard Message "$PD_REDK" RemoteMessage "$PD_REDO" @@ -599,6 +669,7 @@ Lock 129 Chex Lock 130 Chex { + //$Title "Blue key" ChexBlueCard Message "$PD_BLUEK" RemoteMessage "$PD_BLUEO" @@ -608,6 +679,7 @@ Lock 130 Chex Lock 131 Chex { + //$Title "Yellow key" ChexYellowCard Message "$PD_YELLOWK" RemoteMessage "$PD_YELLOWO" From 7ded355d5dde1c3f396a9562e8d7356c40fb7cda Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 4 Jul 2016 13:58:49 -0500 Subject: [PATCH 12/12] Added rollcenter compatibility. --- src/actor.h | 1 + src/thingdef/thingdef_data.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/actor.h b/src/actor.h index 30c4e842a2..93d2834a8f 100644 --- a/src/actor.h +++ b/src/actor.h @@ -412,6 +412,7 @@ enum ActorRenderFlag RF_INVISIBLE = 0x8000, // Don't bother drawing this actor RF_ROLLSPRITE = 0x40000, //[marrub]roll the sprite billboard RF_DONTFLIP = 0x80000, // Don't flip it when viewed from behind. + RF_ROLLCENTER = 0x100000, // Rotate from the center of sprite instead of offsets RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting) RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting) diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index b9e6414ffd..a86e98566b 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -270,6 +270,7 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG(RF, FLATSPRITE, AActor, renderflags), DEFINE_FLAG(RF, WALLSPRITE, AActor, renderflags), DEFINE_FLAG(RF, DONTFLIP, AActor, renderflags), + DEFINE_FLAG(RF, ROLLCENTER, AActor, renderflags), // Bounce flags DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),