From 4ece7d1188f2d0718231997ff36690727cc027a5 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Thu, 11 Aug 2022 13:25:43 +0300 Subject: [PATCH] Workaround for wrong animate_rotation usage Closes #128 --- src/interpreter_extra.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/interpreter_extra.cc b/src/interpreter_extra.cc index 958a9fd..d8997b9 100644 --- a/src/interpreter_extra.cc +++ b/src/interpreter_extra.cc @@ -3340,10 +3340,26 @@ static void opMetarule(Program* program) // 0x4598BC static void opAnim(Program* program) { - int frame = programStackPopInteger(program); + ProgramValue frameValue = programStackPopValue(program); int anim = programStackPopInteger(program); Object* obj = static_cast(programStackPopPointer(program)); + // CE: There is a bug in the `animate_rotation` macro in the user-space + // sсripts - instead of passing direction, it passes object. The direction + // argument is thrown away by preprocessor. Original code ignores this bug + // since there is no distiction between integers and pointers. In addition + // there is a guard in the code path below which simply ignores any value + // greater than 6 (so rotation does not change when pointer is passed). + int frame; + if (frameValue.opcode == VALUE_TYPE_INT) { + frame = frameValue.integerValue; + } else if (anim == 1000 && frameValue.opcode == VALUE_TYPE_PTR) { + // Force code path below to skip setting rotation. + frame = ROTATION_COUNT; + } else { + programFatalError("script error: %s: invalid arg 2 to anim", program->name); + } + if (obj == NULL) { scriptPredefinedError(program, "anim", SCRIPT_ERROR_OBJECT_IS_NULL); return;