diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 9e3b19792d..3fe7251b1a 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -5896,6 +5896,17 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp prev.operation = DSGA_OP_EQ; group->adjusts.pop_back(); state.inference = VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO; + if (group->adjusts.size() >= 2) { + DeterministicSpriteGroupAdjust &eq_adjust = group->adjusts[group->adjusts.size() - 1]; + DeterministicSpriteGroupAdjust &prev_op = group->adjusts[group->adjusts.size() - 2]; + if (eq_adjust.type == DSGA_TYPE_NONE && eq_adjust.variable == 0x1A && + prev_op.type == DSGA_TYPE_NONE && prev_op.operation == DSGA_OP_RST) { + prev_op.type = DSGA_TYPE_EQ; + prev_op.add_val = (0xFFFFFFFF >> eq_adjust.shift_num) & eq_adjust.and_mask; + group->adjusts.pop_back(); + state.inference |= VA2AIF_SINGLE_LOAD; + } + } break; } if (prev_inference & VA2AIF_ONE_OR_ZERO) { @@ -5931,6 +5942,12 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp state.inference = VA2AIF_PREV_TERNARY; break; } + if (prev.operation == DSGA_OP_RST && (prev.type == DSGA_TYPE_EQ || prev.type == DSGA_TYPE_NEQ)) { + prev.type = (prev.type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ; + group->adjusts.pop_back(); + state.inference = VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO | VA2AIF_SINGLE_LOAD; + break; + } } if (adjust.and_mask <= 1) state.inference = prev_inference & (VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO); break; diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 75a6972737..5db003042f 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -157,6 +157,8 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver switch (adjust.type) { case DSGA_TYPE_DIV: value = ((S)value + (S)adjust.add_val) / (S)adjust.divmod_val; break; case DSGA_TYPE_MOD: value = ((S)value + (S)adjust.add_val) % (S)adjust.divmod_val; break; + case DSGA_TYPE_EQ: value = (value == adjust.add_val) ? 1 : 0; break; + case DSGA_TYPE_NEQ: value = (value != adjust.add_val) ? 1 : 0; break; case DSGA_TYPE_NONE: break; } @@ -765,7 +767,9 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint p += seprintf(p, lastof(this->buffer), ", shift: %X, and: %X", adjust.shift_num, adjust.and_mask); switch (adjust.type) { case DSGA_TYPE_DIV: p += seprintf(p, lastof(this->buffer), ", add: %X, div: %X", adjust.add_val, adjust.divmod_val); break; - case DSGA_TYPE_MOD: p += seprintf(p, lastof(this->buffer), ", add: %X, mod: %X", adjust.add_val, adjust.divmod_val); break; + case DSGA_TYPE_MOD: p += seprintf(p, lastof(this->buffer), ", add: %X, mod: %X", adjust.add_val, adjust.divmod_val); break; + case DSGA_TYPE_EQ: p += seprintf(p, lastof(this->buffer), ", eq: %X", adjust.add_val); break; + case DSGA_TYPE_NEQ: p += seprintf(p, lastof(this->buffer), ", neq: %X", adjust.add_val); break; case DSGA_TYPE_NONE: break; } p += seprintf(p, lastof(this->buffer), ", op: %X (%s)", adjust.operation, GetAdjustOperationName(adjust.operation)); diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 1b3d273858..3f9b5d34e1 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -146,6 +146,9 @@ enum DeterministicSpriteGroupAdjustType { DSGA_TYPE_NONE, DSGA_TYPE_DIV, DSGA_TYPE_MOD, + + DSGA_TYPE_EQ, + DSGA_TYPE_NEQ, }; enum DeterministicSpriteGroupAdjustOperation {