VarAction2: Detect and replace reverse subtract via temp storage
This commit is contained in:
@@ -5739,6 +5739,21 @@ static void NewSpriteGroup(ByteReader *buf)
|
|||||||
replace_with_constant_load(0);
|
replace_with_constant_load(0);
|
||||||
} else {
|
} else {
|
||||||
switch (adjust.operation) {
|
switch (adjust.operation) {
|
||||||
|
case DSGA_OP_SUB:
|
||||||
|
if (adjust.variable == 0x7D && adjust.shift_num == 0 && adjust.and_mask == 0xFFFFFFFF) {
|
||||||
|
DeterministicSpriteGroupAdjust &prev = group->adjusts[group->adjusts.size() - 2];
|
||||||
|
if (group->adjusts.size() >= 3 && prev.operation == DSGA_OP_RST) {
|
||||||
|
const DeterministicSpriteGroupAdjust &prev2 = group->adjusts[group->adjusts.size() - 3];
|
||||||
|
if (prev2.operation == DSGA_OP_STO && prev2.type == DSGA_TYPE_NONE && prev2.variable == 0x1A &&
|
||||||
|
prev2.shift_num == 0 && prev2.and_mask == adjust.parameter) {
|
||||||
|
/* Convert: store, load var, subtract stored --> (dead) store, reverse subtract var */
|
||||||
|
prev.operation = DSGA_OP_RSUB;
|
||||||
|
group->adjusts.pop_back();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DSGA_OP_SMIN:
|
case DSGA_OP_SMIN:
|
||||||
if (adjust.variable == 0x1A && adjust.shift_num == 0 && adjust.and_mask == 1) {
|
if (adjust.variable == 0x1A && adjust.shift_num == 0 && adjust.and_mask == 1) {
|
||||||
DeterministicSpriteGroupAdjust &prev = group->adjusts[group->adjusts.size() - 2];
|
DeterministicSpriteGroupAdjust &prev = group->adjusts[group->adjusts.size() - 2];
|
||||||
|
@@ -189,6 +189,7 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver
|
|||||||
case DSGA_OP_SGE: return ((S)last_value >= (S)value) ? 1 : 0;
|
case DSGA_OP_SGE: return ((S)last_value >= (S)value) ? 1 : 0;
|
||||||
case DSGA_OP_SLE: return ((S)last_value <= (S)value) ? 1 : 0;
|
case DSGA_OP_SLE: return ((S)last_value <= (S)value) ? 1 : 0;
|
||||||
case DSGA_OP_SGT: return ((S)last_value > (S)value) ? 1 : 0;
|
case DSGA_OP_SGT: return ((S)last_value > (S)value) ? 1 : 0;
|
||||||
|
case DSGA_OP_RSUB: return value - last_value;
|
||||||
default: return value;
|
default: return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -556,6 +557,7 @@ static const char *_dsg_op_special_names[] {
|
|||||||
"SGE",
|
"SGE",
|
||||||
"SLE",
|
"SLE",
|
||||||
"SGT",
|
"SGT",
|
||||||
|
"RSUB",
|
||||||
};
|
};
|
||||||
static_assert(lengthof(_dsg_op_special_names) == DSGA_OP_SPECIAL_END - DSGA_OP_TERNARY);
|
static_assert(lengthof(_dsg_op_special_names) == DSGA_OP_SPECIAL_END - DSGA_OP_TERNARY);
|
||||||
|
|
||||||
|
@@ -168,6 +168,7 @@ enum DeterministicSpriteGroupAdjustOperation {
|
|||||||
DSGA_OP_SGE, ///< (signed) a >= b ? 1 : 0,
|
DSGA_OP_SGE, ///< (signed) a >= b ? 1 : 0,
|
||||||
DSGA_OP_SLE, ///< (signed) a <= b ? 1 : 0,
|
DSGA_OP_SLE, ///< (signed) a <= b ? 1 : 0,
|
||||||
DSGA_OP_SGT, ///< (signed) a > b ? 1 : 0,
|
DSGA_OP_SGT, ///< (signed) a > b ? 1 : 0,
|
||||||
|
DSGA_OP_RSUB, ///< b - a
|
||||||
|
|
||||||
DSGA_OP_SPECIAL_END,
|
DSGA_OP_SPECIAL_END,
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user