From 58060a8c5f7b300c4489f33cfc4ca9c936defce8 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Mon, 23 Mar 2020 13:52:28 +0800 Subject: [PATCH] Simplified the pushad/popad in _WRAP_OPCODE macro Refactored ASM code of art_exists and sneak_success functions. Rewrote set_critter_current_ap and set_sfall_arg with _WRAP_OPCODE. --- sfall/FalloutEngine.cpp | 4 +++ sfall/FalloutEngine.h | 2 ++ sfall/ScriptExtender.cpp | 36 +++++++------------- sfall/ScriptOps/AsmMacros.h | 6 ++-- sfall/ScriptOps/MiscOps.hpp | 8 ++--- sfall/ScriptOps/ObjectsOps.hpp | 15 ++++----- sfall/ScriptOps/StatsOps.hpp | 60 ++++++++++++---------------------- 7 files changed, 52 insertions(+), 79 deletions(-) diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index ef5dcc7b..3ac0a86f 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -1452,6 +1452,10 @@ void __stdcall IntfaceUpdateAc(long animate) { WRAP_WATCOM_CALL1(intface_update_ac_, animate) } +void __stdcall IntfaceUpdateMovePoints(long ap, long freeAP) { + WRAP_WATCOM_CALL2(intface_update_move_points_, ap, freeAP) +} + void __fastcall IntfaceUpdateItems(long animate, long modeLeft, long modeRight) { WRAP_WATCOM_FCALL3(intface_update_items_, animate, modeLeft, modeRight) } diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 6eb0dfe3..23981fff 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -1297,6 +1297,8 @@ void __fastcall CorrectFidForRemovedItemFunc(TGameObj* critter, TGameObj* item, void __stdcall IntfaceUpdateAc(long animate); +void __stdcall IntfaceUpdateMovePoints(long ap, long freeAP); + void __fastcall IntfaceUpdateItems(long animate, long modeLeft, long modeRight); long __stdcall InvenUnwield(TGameObj* critter, long slot); diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 55f99c8e..288530b5 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -675,33 +675,21 @@ static void __declspec(naked) GetSfallArgs() { } } -static void __declspec(naked) SetSfallArg() { - __asm { - pushad; - mov ecx, eax; - call interpretPopShort_; - mov edi, eax; - mov eax, ecx; - call interpretPopLong_; - mov edx, eax; - mov eax, ecx; - call interpretPopShort_; - mov esi, eax; - mov eax, ecx; - call interpretPopLong_; - cmp di, VAR_TYPE_INT; - jnz end; - cmp si, VAR_TYPE_INT; - jnz end; - push edx; - push eax; - call SetHSArg; -end: - popad; - retn; +static void _stdcall SetSfallArg2() { + const ScriptValue &argNumArg = opHandler.arg(0), + &valArg = opHandler.arg(1); + + if (argNumArg.isInt() && valArg.isInt()) { + SetHSArg(argNumArg.rawValue(), valArg.rawValue()); + } else { + OpcodeInvalidArgs("set_sfall_arg"); } } +static void __declspec(naked) SetSfallArg() { + _WRAP_OPCODE(SetSfallArg2, 2, 0) +} + static void __declspec(naked) SetSfallReturn() { __asm { mov esi, ecx; diff --git a/sfall/ScriptOps/AsmMacros.h b/sfall/ScriptOps/AsmMacros.h index f5e025d4..66112a27 100644 --- a/sfall/ScriptOps/AsmMacros.h +++ b/sfall/ScriptOps/AsmMacros.h @@ -186,13 +186,13 @@ __asm resultnotstr##num: \ isExpression - 1 if opcode has return value, 0 otherwise */ #define _WRAP_OPCODE(func, argnum, isExpression) __asm { \ - __asm pushad \ + __asm push ecx \ __asm push isExpression \ __asm push argnum \ __asm push func \ __asm push eax \ - __asm lea ecx, opHandler \ + __asm lea ecx, opHandler \ __asm call OpcodeHandler::handleOpcode \ - __asm popad \ + __asm pop ecx \ __asm retn \ } diff --git a/sfall/ScriptOps/MiscOps.hpp b/sfall/ScriptOps/MiscOps.hpp index bad27da2..d31880df 100644 --- a/sfall/ScriptOps/MiscOps.hpp +++ b/sfall/ScriptOps/MiscOps.hpp @@ -1091,12 +1091,12 @@ static void sf_attack_is_aimed() { } static void __declspec(naked) op_sneak_success() { - _OP_BEGIN(ebp) __asm { - call is_pc_sneak_working_ + call is_pc_sneak_working_; + mov edx, eax; + mov eax, ebx; + _J_RET_VAL_TYPE(VAR_TYPE_INT); } - _RET_VAL_INT32(ebp) - _OP_END } static void _stdcall op_tile_light2() { diff --git a/sfall/ScriptOps/ObjectsOps.hpp b/sfall/ScriptOps/ObjectsOps.hpp index 8c017563..a7effd0b 100644 --- a/sfall/ScriptOps/ObjectsOps.hpp +++ b/sfall/ScriptOps/ObjectsOps.hpp @@ -446,18 +446,17 @@ static void __declspec(naked) op_get_party_members() { } static void __declspec(naked) op_art_exists() { - _OP_BEGIN(ebp) - _GET_ARG_R32(ebp, ecx, eax) - _CHECK_ARG_INT(cx, fail) __asm { + _GET_ARG_INT(fail); call art_exists_; - jmp end; -fail: - xor eax, eax; + mov edx, eax; end: + mov eax, ebx; + _J_RET_VAL_TYPE(VAR_TYPE_INT); +fail: + xor edx, edx; // return 0 + jmp end; } - _RET_VAL_INT32(ebp) - _OP_END } static void _stdcall op_obj_is_carrying_obj2() { diff --git a/sfall/ScriptOps/StatsOps.hpp b/sfall/ScriptOps/StatsOps.hpp index b14f1184..4c4c1ac5 100644 --- a/sfall/ScriptOps/StatsOps.hpp +++ b/sfall/ScriptOps/StatsOps.hpp @@ -377,49 +377,29 @@ fail: } } -static void __declspec(naked) SetCritterAP() { - __asm { - //Store registers - push ebx; - push ecx; - push edx; - push edi; - push esi; - //Get function args - mov ecx, eax; - call interpretPopShort_; - mov edi, eax; - mov eax, ecx; - call interpretPopLong_; - mov ebx, eax; - mov eax, ecx; - call interpretPopShort_; - mov esi, eax; - mov eax, ecx; - call interpretPopLong_; - //Check args are valid - cmp di, VAR_TYPE_INT; - jnz end; - cmp si, VAR_TYPE_INT; - jnz end; - mov [eax + 0x40], ebx; - mov ecx, ds:[_obj_dude] - cmp ecx, eax; - jne end; - mov eax, ebx; - mov edx, ds:[_combat_free_move] - call intface_update_move_points_; -end: - //Restore registers and return - pop esi; - pop edi; - pop edx; - pop ecx; - pop ebx; - retn; +static void _stdcall SetCritterAP2() { + TGameObj* obj = opHandler.arg(0).asObject(); + const ScriptValue &apArg = opHandler.arg(1); + + if (obj && apArg.isInt()) { + if (obj->pid >> 24 == OBJ_TYPE_CRITTER) { + long ap = apArg.rawValue(); + if (ap < 0) ap = 0; + obj->critterAP_weaponAmmoPid = ap; + + if (obj == *ptr_obj_dude) IntfaceUpdateMovePoints(ap, *ptr_combat_free_move); + } else { + opHandler.printOpcodeError(objNotCritter, "set_critter_current_ap"); + } + } else { + OpcodeInvalidArgs("set_critter_current_ap"); } } +static void __declspec(naked) SetCritterAP() { + _WRAP_OPCODE(SetCritterAP2, 2, 0) +} + static void __declspec(naked) fSetPickpocketMax() { __asm { mov esi, ecx;