From 6e9f1ae51734d583d949375a7c0fefd291b3c456 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 3 Sep 2023 18:23:19 +0300 Subject: [PATCH] Add op_set_self --- src/interpreter_extra.cc | 23 +++++++++++++++++++++-- src/scripts.cc | 2 ++ src/scripts.h | 2 ++ src/sfall_opcodes.cc | 14 ++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/interpreter_extra.cc b/src/interpreter_extra.cc index b2d3295..ca3e5e0 100644 --- a/src/interpreter_extra.cc +++ b/src/interpreter_extra.cc @@ -1580,12 +1580,22 @@ static void opPickup(Program* program) return; } - if (script->target == NULL) { + Object* self = script->target; + + // SFALL: Override `self` via `op_set_self`. + // CE: Implementation is different. Sfall integrates via `scriptGetSid` by + // returning fake script with overridden `self` (and `target` in this case). + if (script->overriddenSelf != nullptr) { + self = script->overriddenSelf; + script->overriddenSelf = nullptr; + } + + if (self == NULL) { scriptPredefinedError(program, "pickup_obj", SCRIPT_ERROR_OBJECT_IS_NULL); return; } - actionPickUp(script->target, object); + actionPickUp(self, object); } // drop_obj @@ -4548,6 +4558,15 @@ static void opUseObjectOnObject(Program* program) } Object* self = scriptGetSelf(program); + + // SFALL: Override `self` via `op_set_self`. + // CE: Implementation is different. Sfall integrates via `scriptGetSid` by + // returning fake script with overridden `self`. + if (script->overriddenSelf != nullptr) { + self = script->overriddenSelf; + script->overriddenSelf = nullptr; + } + if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) { _action_use_an_item_on_object(self, target, item); } else { diff --git a/src/scripts.cc b/src/scripts.cc index 58dab5d..1485fff 100644 --- a/src/scripts.cc +++ b/src/scripts.cc @@ -2214,6 +2214,8 @@ int scriptAdd(int* sidPtr, int scriptType) scr->procs[index] = SCRIPT_PROC_NO_PROC; } + scr->overriddenSelf = nullptr; + scriptListExtent->length++; return 0; diff --git a/src/scripts.h b/src/scripts.h index 5cc3220..782591c 100644 --- a/src/scripts.h +++ b/src/scripts.h @@ -143,6 +143,8 @@ typedef struct Script { int field_D4; int field_D8; int field_DC; + + Object* overriddenSelf; } Script; extern const char* gScriptProcNames[SCRIPT_PROC_COUNT]; diff --git a/src/sfall_opcodes.cc b/src/sfall_opcodes.cc index d070539..d202c1b 100644 --- a/src/sfall_opcodes.cc +++ b/src/sfall_opcodes.cc @@ -345,6 +345,19 @@ static void op_set_proto_data(Program* program) *reinterpret_cast(reinterpret_cast(proto) + offset) = value; } +// set_self +static void op_set_self(Program* program) +{ + Object* obj = static_cast(programStackPopPointer(program)); + + int sid = scriptGetSid(program); + + Script* scr; + if (scriptGetScript(sid, &scr) == 0) { + scr->overriddenSelf = obj; + } +} + // list_begin static void opListBegin(Program* program) { @@ -1055,6 +1068,7 @@ void sfallOpcodesInit() interpreterRegisterOpcode(0x81F5, op_get_script); interpreterRegisterOpcode(0x8204, op_get_proto_data); interpreterRegisterOpcode(0x8205, op_set_proto_data); + interpreterRegisterOpcode(0x8206, op_set_self); interpreterRegisterOpcode(0x820D, opListBegin); interpreterRegisterOpcode(0x820E, opListNext); interpreterRegisterOpcode(0x820F, opListEnd);