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.
This commit is contained in:
NovaRain
2020-03-23 13:52:28 +08:00
parent 22140e2a0c
commit 58060a8c5f
7 changed files with 52 additions and 79 deletions
+4
View File
@@ -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)
}
+2
View File
@@ -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);
+12 -24
View File
@@ -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;
+2 -2
View File
@@ -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 call OpcodeHandler::handleOpcode \
__asm popad \
__asm pop ecx \
__asm retn \
}
+4 -4
View File
@@ -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() {
+7 -8
View File
@@ -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() {
+20 -40
View File
@@ -377,47 +377,27 @@ 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() {