Rewrote various script functions in _WRAP_OPCODE

* funcs: reg_anim_*, sqrt, sin, cos, tan, arctan, get/set_weapon_ammo_*,
list_*, strlen, atoi, atof, typeof, string_split.
This commit is contained in:
NovaRain
2020-03-24 12:12:34 +08:00
parent f6ae7c5f2c
commit 7cbde234c6
11 changed files with 361 additions and 697 deletions
+24
View File
@@ -990,6 +990,30 @@ long __stdcall ScrPtr(long scriptId, TScript** scriptPtr) {
WRAP_WATCOM_CALL2(scr_ptr_, scriptId, scriptPtr)
}
long __stdcall RegisterObjectAnimateAndHide(TGameObj* object, long anim, long delay) {
WRAP_WATCOM_CALL3(register_object_animate_and_hide_, object, anim, delay)
}
long __stdcall RegisterObjectChangeFid(TGameObj* object, long artFid, long delay) {
WRAP_WATCOM_CALL3(register_object_change_fid_, object, artFid, delay)
}
long __stdcall RegisterObjectLight(TGameObj* object, long lightRadius, long delay) {
WRAP_WATCOM_CALL3(register_object_light_, object, lightRadius, delay)
}
long __stdcall RegisterObjectMustErase(TGameObj* object) {
WRAP_WATCOM_CALL1(register_object_must_erase_, object)
}
long __stdcall RegisterObjectTakeOut(TGameObj* object, long holdFrameId, long nothing) {
WRAP_WATCOM_CALL3(register_object_take_out_, object, holdFrameId, nothing)
}
long __stdcall RegisterObjectTurnTowards(TGameObj* object, long tileNum, long nothing) {
WRAP_WATCOM_CALL3(register_object_turn_towards_, object, tileNum, nothing)
}
long __stdcall ScrNew(long* scriptID, long sType) {
WRAP_WATCOM_CALL2(scr_new_, scriptID, sType)
}
+7
View File
@@ -1131,6 +1131,13 @@ TGameObj* __stdcall ScrFindObjFromProgram(TProgram* program);
// Returns 0 on success, -1 on failure.
long __stdcall ScrPtr(long scriptId, TScript** scriptPtr);
long __stdcall RegisterObjectAnimateAndHide(TGameObj* object, long anim, long delay);
long __stdcall RegisterObjectChangeFid(TGameObj* object, long artFid, long delay);
long __stdcall RegisterObjectLight(TGameObj* object, long lightRadius, long delay);
long __stdcall RegisterObjectMustErase(TGameObj* object);
long __stdcall RegisterObjectTakeOut(TGameObj* object, long holdFrameId, long nothing);
long __stdcall RegisterObjectTurnTowards(TGameObj* object, long tileNum, long nothing);
long __stdcall ScrNew(long* scriptID, long sType);
long __stdcall ScrRemove(long scriptID);
+3 -3
View File
@@ -538,7 +538,7 @@ long SetGlobalVar(const char* var, int val) {
return 0;
}
static void funcSetGlobalVar2() {
static void _stdcall funcSetGlobalVar2() {
const ScriptValue &varArg = opHandler.arg(0),
&valArg = opHandler.arg(1);
@@ -572,7 +572,7 @@ long GetGlobalVarInt(DWORD var) {
return GetGlobalVarInternal(static_cast<__int64>(var));
}
static void funcGetGlobalVarInt2() {
static void _stdcall funcGetGlobalVarInt2() {
const ScriptValue &varArg = opHandler.arg(0);
long result = 0;
@@ -598,7 +598,7 @@ static void __declspec(naked) funcGetGlobalVarInt() {
_WRAP_OPCODE(funcGetGlobalVarInt2, 1, 1)
}
static void funcGetGlobalVarFloat2() {
static void _stdcall funcGetGlobalVarFloat2() {
const ScriptValue &varArg = opHandler.arg(0);
long result = 0;
+117 -111
View File
@@ -35,142 +35,148 @@ void __stdcall RegAnimCombatCheck(DWORD newValue) {
}
}
static void __declspec(naked) op_reg_anim_combat_check() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, ecx, edx) // new value
_CHECK_ARG_INT(cx, end1)
__asm {
push edx
call RegAnimCombatCheck
}
end1:
_OP_END
// true if combat mode is active and combat check was not disabled
static bool checkCombatMode() {
return (regAnimCombatCheck & *ptr_combat_state) != 0;
}
// new reg_anim functions (all using existing engine code)
static void _stdcall op_reg_anim_combat_check2() {
const ScriptValue &newValArg = opHandler.arg(0);
// checks if combat mode is enabled (using R8 8-bit register) and jumps to GOTOFAIL if it is (does nothing if regAnimCombatCheck is 0)
#define _CHECK_COMBAT_MODE(R8, GOTOFAIL) __asm { \
__asm mov R8, regAnimCombatCheck \
__asm test byte ptr ds:_combat_state, R8 \
__asm jnz GOTOFAIL }
if (newValArg.isInt()) {
RegAnimCombatCheck(newValArg.rawValue());
} else {
OpcodeInvalidArgs("reg_anim_combat_check");
}
}
static void __declspec(naked) op_reg_anim_combat_check() {
_WRAP_OPCODE(op_reg_anim_combat_check2, 1, 0)
}
static void _stdcall op_reg_anim_destroy2() {
TGameObj* obj = opHandler.arg(0).asObject();
if (obj) {
if (!checkCombatMode()) {
RegisterObjectMustErase(obj);
}
} else {
OpcodeInvalidArgs("reg_anim_destroy");
}
}
static void __declspec(naked) op_reg_anim_destroy() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, edx, esi) // object
_CHECK_ARG_INT(dx, end1)
_CHECK_COMBAT_MODE(al, end1)
__asm {
mov eax, esi // object
call register_object_must_erase_;
_WRAP_OPCODE(op_reg_anim_destroy2, 1, 0)
}
static void _stdcall op_reg_anim_animate_and_hide2() {
TGameObj* obj = opHandler.arg(0).asObject();
const ScriptValue &animIdArg = opHandler.arg(1),
&delayArg = opHandler.arg(2);
if (obj && animIdArg.isInt() && delayArg.isInt()) {
if (!checkCombatMode()) {
int animId = animIdArg.rawValue(),
delay = delayArg.rawValue();
RegisterObjectAnimateAndHide(obj, animId, delay);
}
} else {
OpcodeInvalidArgs("reg_anim_animate_and_hide");
}
end1:
_OP_END
}
static void __declspec(naked) op_reg_anim_animate_and_hide() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, ebx, esi) // delay
_GET_ARG_R32(ebp, ecx, edi) // animID
_GET_ARG_R32(ebp, edx, eax) // object
// eax should not change until function call
_CHECK_ARG_INT(bx, end)
_CHECK_ARG_INT(cx, end)
_CHECK_ARG_INT(dx, end)
__asm {
_CHECK_COMBAT_MODE(bl, end)
mov ebx, esi // delay
mov edx, edi // animID
call register_object_animate_and_hide_;
_WRAP_OPCODE(op_reg_anim_animate_and_hide2, 3, 0)
}
static void _stdcall op_reg_anim_light2() {
TGameObj* obj = opHandler.arg(0).asObject();
const ScriptValue &radiusArg = opHandler.arg(1),
&delayArg = opHandler.arg(2);
if (obj && radiusArg.isInt() && delayArg.isInt()) {
if (!checkCombatMode()) {
int radius = radiusArg.rawValue(),
delay = delayArg.rawValue();
if (radius < 0) {
radius = 0;
} else if (radius > 8) {
radius = 8;
}
RegisterObjectLight(obj, radius, delay);
}
} else {
OpcodeInvalidArgs("reg_anim_light");
}
end:
_OP_END
}
static void __declspec(naked) op_reg_anim_light() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, ebx, esi) // delay
_GET_ARG_R32(ebp, ecx, edi) // light radius
_GET_ARG_R32(ebp, edx, eax) // object
// eax should not change until function call
_CHECK_ARG_INT(bx, end)
_CHECK_ARG_INT(cx, end)
_CHECK_ARG_INT(dx, end)
__asm {
// check for valid radius
cmp di, 0
jge dontfixMin
mov di, 0
jmp dontfixMax
dontfixMin:
cmp di, 8
jle dontfixMax
mov di, 8
dontfixMax:
_CHECK_COMBAT_MODE(bl, end)
mov ebx, esi // delay
mov edx, edi // light radius
call register_object_light_;
_WRAP_OPCODE(op_reg_anim_light2, 3, 0)
}
static void _stdcall op_reg_anim_change_fid2() {
TGameObj* obj = opHandler.arg(0).asObject();
const ScriptValue &fidArg = opHandler.arg(1),
&delayArg = opHandler.arg(2);
if (obj && fidArg.isInt() && delayArg.isInt()) {
if (!checkCombatMode()) {
int fid = fidArg.rawValue(),
delay = delayArg.rawValue();
RegisterObjectChangeFid(obj, fid, delay);
}
} else {
OpcodeInvalidArgs("reg_anim_change_fid");
}
end:
_OP_END
}
static void __declspec(naked) op_reg_anim_change_fid() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, ebx, esi) // delay
_GET_ARG_R32(ebp, ecx, edi) // FID
_GET_ARG_R32(ebp, edx, eax) // object
// eax should not change until function call
_CHECK_ARG_INT(bx, end)
_CHECK_ARG_INT(cx, end)
_CHECK_ARG_INT(dx, end)
__asm {
_CHECK_COMBAT_MODE(bl, end)
mov ebx, esi // delay
mov edx, edi // FID
call register_object_change_fid_
_WRAP_OPCODE(op_reg_anim_change_fid2, 3, 0)
}
static void _stdcall op_reg_anim_take_out2() {
TGameObj* obj = opHandler.arg(0).asObject();
const ScriptValue &holdFrameArg = opHandler.arg(1),
&nothingArg = opHandler.arg(2);
if (obj && holdFrameArg.isInt() && nothingArg.isInt()) {
if (!checkCombatMode()) {
int holdFrame = holdFrameArg.rawValue(),
nothing = nothingArg.rawValue(); // not used by engine
RegisterObjectTakeOut(obj, holdFrame, nothing);
}
} else {
OpcodeInvalidArgs("reg_anim_take_out");
}
end:
_OP_END
}
static void __declspec(naked) op_reg_anim_take_out() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, ebx, esi) // delay - not used
_GET_ARG_R32(ebp, ecx, edi) // weapon hold frame ID
_GET_ARG_R32(ebp, edx, eax) // object
// eax should not change until function call
_CHECK_ARG_INT(bx, end)
_CHECK_ARG_INT(cx, end)
_CHECK_ARG_INT(dx, end)
__asm {
_CHECK_COMBAT_MODE(bl, end)
//mov ebx, esi // delay - not used
mov edx, edi // holdFrame
call register_object_take_out_;
_WRAP_OPCODE(op_reg_anim_take_out2, 3, 0)
}
static void _stdcall op_reg_anim_turn_towards2() {
TGameObj* obj = opHandler.arg(0).asObject();
const ScriptValue &tileArg = opHandler.arg(1),
&nothingArg = opHandler.arg(2);
if (obj && tileArg.isInt() && nothingArg.isInt()) {
if (!checkCombatMode()) {
int tile = tileArg.rawValue(),
nothing = nothingArg.rawValue(); // not used by engine
RegisterObjectTurnTowards(obj, tile, nothing);
}
} else {
OpcodeInvalidArgs("reg_anim_turn_towards");
}
end:
_OP_END
}
static void __declspec(naked) op_reg_anim_turn_towards() {
_OP_BEGIN(ebp)
_GET_ARG_R32(ebp, ebx, esi) // delay - not used
_GET_ARG_R32(ebp, ecx, edi) // tile
_GET_ARG_R32(ebp, edx, eax) // object
// eax should not change until function call
_CHECK_ARG_INT(bx, end)
_CHECK_ARG_INT(cx, end)
_CHECK_ARG_INT(dx, end)
__asm {
_CHECK_COMBAT_MODE(bl, end)
// mov ebx, esi // delay - not used
mov edx, edi // tile
call register_object_turn_towards_;
}
end:
_OP_END
_WRAP_OPCODE(op_reg_anim_turn_towards2, 3, 0)
}
static void __declspec(naked) ExecuteCallback() {
-24
View File
@@ -79,20 +79,6 @@
__asm mov outVal, eax \
}
/*
checks argument to be integer, and jumps to GOTOFAIL if it's not
*/
#define _CHECK_ARG_INT(r16type, GOTOFAIL) __asm { \
__asm cmp r16type, VAR_TYPE_INT \
__asm jne GOTOFAIL }
/*
checks argument to be float, and jumps to GOTOFAIL if it's not
*/
#define _CHECK_ARG_FLOAT(r16type, GOTOFAIL) __asm { \
__asm cmp r16type, VAR_TYPE_FLOAT \
__asm jne GOTOFAIL }
/*
checks argument (which may be any type) if it's a string and retrieves it (overwrites value in rval)
num - any number, but it must be unique (used for label names)
@@ -122,16 +108,6 @@ notstring##num:
__asm call interpretPushShort_ \
}
// return value stored in EAX as float
#define _RET_VAL_FLOAT(rscript) __asm { \
__asm mov edx, eax \
__asm mov eax, rscript \
__asm call interpretPushLong_ \
__asm mov edx, VAR_TYPE_FLOAT \
__asm mov eax, rscript \
__asm call interpretPushShort_ \
}
/*
Returns the value to the script
eax and ebx register must contain the script_ptr
+17 -17
View File
@@ -23,7 +23,7 @@
#include "ScriptExtender.h"
//file system functions
static void fs_create2() {
static void _stdcall fs_create2() {
const ScriptValue &pathArg = opHandler.arg(0),
&sizeArg = opHandler.arg(1);
@@ -39,7 +39,7 @@ static void __declspec(naked) fs_create() {
_WRAP_OPCODE(fs_create2, 2, 1)
}
static void fs_copy2() {
static void _stdcall fs_copy2() {
const ScriptValue &pathArg = opHandler.arg(0),
&srcArg = opHandler.arg(1);
@@ -55,7 +55,7 @@ static void __declspec(naked) fs_copy() {
_WRAP_OPCODE(fs_copy2, 2, 1)
}
static void fs_find2() {
static void _stdcall fs_find2() {
const ScriptValue &pathArg = opHandler.arg(0);
if (pathArg.isString()) {
@@ -70,7 +70,7 @@ static void __declspec(naked) fs_find() {
_WRAP_OPCODE(fs_find2, 1, 1)
}
static void fs_write_byte2() {
static void _stdcall fs_write_byte2() {
const ScriptValue &idArg = opHandler.arg(0),
&dataArg = opHandler.arg(1);
@@ -85,7 +85,7 @@ static void __declspec(naked) fs_write_byte() {
_WRAP_OPCODE(fs_write_byte2, 2, 0)
}
static void fs_write_short2() {
static void _stdcall fs_write_short2() {
const ScriptValue &idArg = opHandler.arg(0),
&dataArg = opHandler.arg(1);
@@ -100,7 +100,7 @@ static void __declspec(naked) fs_write_short() {
_WRAP_OPCODE(fs_write_short2, 2, 0)
}
static void fs_write_int2() {
static void _stdcall fs_write_int2() {
const ScriptValue &idArg = opHandler.arg(0),
&dataArg = opHandler.arg(1);
@@ -115,7 +115,7 @@ static void __declspec(naked) fs_write_int() {
_WRAP_OPCODE(fs_write_int2, 2, 0)
}
static void fs_write_string2() {
static void _stdcall fs_write_string2() {
const ScriptValue &idArg = opHandler.arg(0),
&dataArg = opHandler.arg(1);
@@ -130,7 +130,7 @@ static void __declspec(naked) fs_write_string() {
_WRAP_OPCODE(fs_write_string2, 2, 0)
}
static void fs_write_bstring2() {
static void _stdcall fs_write_bstring2() {
const ScriptValue &idArg = opHandler.arg(0),
&dataArg = opHandler.arg(1);
@@ -145,7 +145,7 @@ static void __declspec(naked) fs_write_bstring() {
_WRAP_OPCODE(fs_write_bstring2, 2, 0)
}
static void fs_read_byte2() {
static void _stdcall fs_read_byte2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
@@ -160,7 +160,7 @@ static void __declspec(naked) fs_read_byte() {
_WRAP_OPCODE(fs_read_byte2, 1, 1)
}
static void fs_read_short2() {
static void _stdcall fs_read_short2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
@@ -175,7 +175,7 @@ static void __declspec(naked) fs_read_short() {
_WRAP_OPCODE(fs_read_short2, 1, 1)
}
static void fs_read_int2() {
static void _stdcall fs_read_int2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
@@ -190,7 +190,7 @@ static void __declspec(naked) fs_read_int() {
_WRAP_OPCODE(fs_read_int2, 1, 1)
}
static void fs_read_float2() {
static void _stdcall fs_read_float2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
@@ -205,7 +205,7 @@ static void __declspec(naked) fs_read_float() {
_WRAP_OPCODE(fs_read_float2, 1, 1)
}
static void fs_delete2() {
static void _stdcall fs_delete2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
@@ -219,7 +219,7 @@ static void __declspec(naked) fs_delete() {
_WRAP_OPCODE(fs_delete2, 1, 0)
}
static void fs_size2() {
static void _stdcall fs_size2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
@@ -234,7 +234,7 @@ static void __declspec(naked) fs_size() {
_WRAP_OPCODE(fs_size2, 1, 1)
}
static void fs_pos2() {
static void _stdcall fs_pos2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
@@ -249,7 +249,7 @@ static void __declspec(naked) fs_pos() {
_WRAP_OPCODE(fs_pos2, 1, 1)
}
static void fs_seek2() {
static void _stdcall fs_seek2() {
const ScriptValue &idArg = opHandler.arg(0),
&posArg = opHandler.arg(1);
@@ -264,7 +264,7 @@ static void __declspec(naked) fs_seek() {
_WRAP_OPCODE(fs_seek2, 2, 0)
}
static void fs_resize2() {
static void _stdcall fs_resize2() {
const ScriptValue &idArg = opHandler.arg(0),
&sizeArg = opHandler.arg(1);
+1 -1
View File
@@ -310,7 +310,7 @@ static void __declspec(naked) HideIfaceTag() {
_WRAP_OPCODE(HideIfaceTag2, 1, 0)
}
static void IsIfaceTagActive2() {
static void _stdcall IsIfaceTagActive2() {
const ScriptValue &tagArg = opHandler.arg(0);
if (tagArg.isInt()) {
bool result = false;
+58 -202
View File
@@ -49,46 +49,21 @@ static void __declspec(naked) funcDiv() {
_WRAP_OPCODE(funcDiv2, 2, 1)
}
static void __declspec(naked) funcSqrt() {
__asm {
pushad;
sub esp, 4;
mov ecx, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ecx;
call interpretPopLong_;
cmp bx, VAR_TYPE_INT;
jnz arg1l2;
mov [esp], eax;
fild [esp];
jmp calc;
arg1l2:
cmp bx, VAR_TYPE_FLOAT;
jnz fail;
mov [esp], eax;
fld [esp];
calc:
fsqrt;
fstp [esp];
mov edx, [esp];
jmp end;
fail:
fldz;
fstp [esp];
mov edx, [esp];
end:
mov eax, ecx;
call interpretPushLong_;
mov edx, VAR_TYPE_FLOAT;
mov eax, ecx;
call interpretPushShort_;
add esp, 4;
popad;
retn;
static void _stdcall funcSqrt2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(sqrt(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("sqrt");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcSqrt() {
_WRAP_OPCODE(funcSqrt2, 1, 1)
}
static void _stdcall funcAbs2() {
const ScriptValue &value = opHandler.arg(0);
@@ -108,184 +83,65 @@ static void __declspec(naked) funcAbs() {
_WRAP_OPCODE(funcAbs2, 1, 1)
}
static void _stdcall funcSin2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(sin(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("sin");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcSin() {
__asm {
pushad;
sub esp, 4;
mov ecx, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ecx;
call interpretPopLong_;
cmp bx, VAR_TYPE_INT;
jnz arg1l2;
mov [esp], eax;
fild [esp];
jmp calc;
arg1l2:
cmp bx, VAR_TYPE_FLOAT;
jnz fail;
mov [esp], eax;
fld [esp];
calc:
fsin;
fstp [esp];
mov edx, [esp];
jmp end;
fail:
fldz;
fstp [esp];
mov edx, [esp];
end:
mov eax, ecx;
call interpretPushLong_;
mov edx, VAR_TYPE_FLOAT;
mov eax, ecx;
call interpretPushShort_;
add esp, 4;
popad;
retn;
_WRAP_OPCODE(funcSin2, 1, 1)
}
static void _stdcall funcCos2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(cos(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("cos");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcCos() {
__asm {
pushad;
sub esp, 4;
mov ecx, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ecx;
call interpretPopLong_;
cmp bx, VAR_TYPE_INT;
jnz arg1l2;
mov [esp], eax;
fild [esp];
jmp calc;
arg1l2:
cmp bx, VAR_TYPE_FLOAT;
jnz fail;
mov [esp], eax;
fld [esp];
calc:
fcos;
fstp [esp];
mov edx, [esp];
jmp end;
fail:
fldz;
fstp [esp];
mov edx, [esp];
end:
mov eax, ecx;
call interpretPushLong_;
mov edx, VAR_TYPE_FLOAT;
mov eax, ecx;
call interpretPushShort_;
add esp, 4;
popad;
retn;
_WRAP_OPCODE(funcCos2, 1, 1)
}
static void _stdcall funcTan2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(tan(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("tan");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcTan() {
__asm {
pushad;
sub esp, 4;
mov ecx, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ecx;
call interpretPopLong_;
cmp bx, VAR_TYPE_INT;
jnz arg1l2;
mov [esp], eax;
fild [esp];
jmp calc;
arg1l2:
cmp bx, VAR_TYPE_FLOAT;
jnz fail;
mov [esp], eax;
fld [esp];
calc:
fptan;
fstp [esp];
fstp [esp];
mov edx, [esp];
jmp end;
fail:
fldz;
fstp [esp];
mov edx, [esp];
end:
mov eax, ecx;
call interpretPushLong_;
mov edx, VAR_TYPE_FLOAT;
mov eax, ecx;
call interpretPushShort_;
add esp, 4;
popad;
retn;
_WRAP_OPCODE(funcTan2, 1, 1)
}
static void _stdcall funcATan2() {
const ScriptValue &xFltArg = opHandler.arg(0),
&yFltArg = opHandler.arg(1);
if (!xFltArg.isString() && !yFltArg.isString()) {
opHandler.setReturn(atan2(xFltArg.asFloat(), yFltArg.asFloat()));
} else {
OpcodeInvalidArgs("arctan");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcATan() {
__asm {
pushad;
sub esp, 4;
mov ecx, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ecx;
call interpretPopLong_;
mov edi, eax;
mov eax, ecx;
call interpretPopShort_;
mov edx, eax;
mov eax, ecx;
call interpretPopLong_;
cmp bx, VAR_TYPE_INT;
jnz arg1l2;
mov [esp], eax;
fild [esp];
jmp arg2l1;
arg1l2:
cmp bx, VAR_TYPE_FLOAT;
jnz fail;
mov [esp], eax;
fld [esp];
arg2l1:
cmp dx, VAR_TYPE_INT;
jnz arg2l2;
mov [esp], edi;
fild [esp];
jmp calc;
arg2l2:
cmp dx, VAR_TYPE_FLOAT;
jnz fail2;
mov [esp], edi;
fld [esp];
calc:
fpatan;
fstp [esp];
mov edx, [esp];
jmp end;
fail2:
fstp [esp];
fail:
fldz;
fstp [esp];
mov edx, [esp];
end:
mov eax, ecx;
call interpretPushLong_;
mov edx, VAR_TYPE_FLOAT;
mov eax, ecx;
call interpretPushShort_;
add esp, 4;
popad;
retn;
}
_WRAP_OPCODE(funcATan2, 2, 1)
}
static void _stdcall funcPow2() {
+44 -95
View File
@@ -163,113 +163,62 @@ static void __declspec(naked) set_critter_burst_disable() {
_WRAP_OPCODE(set_critter_burst_disable2, 2, 0)
}
static void _stdcall get_weapon_ammo_pid2() {
TGameObj* obj = opHandler.arg(0).asObject();
if (obj) {
opHandler.setReturn(obj->critterAP_weaponAmmoPid);
} else {
OpcodeInvalidArgs("get_weapon_ammo_pid");
opHandler.setReturn(-1);
}
}
static void __declspec(naked) get_weapon_ammo_pid() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz fail;
test eax, eax;
jz fail;
mov edx, [eax+0x40];
jmp end;
fail:
xor edx, edx;
dec edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov eax, ebp;
mov edx, VAR_TYPE_INT;
call interpretPushShort_;
popad;
retn;
_WRAP_OPCODE(get_weapon_ammo_pid2, 1, 1)
}
static void _stdcall set_weapon_ammo_pid2() {
TGameObj* obj = opHandler.arg(0).asObject();
const ScriptValue &pidArg = opHandler.arg(1);
if (obj && pidArg.isInt()) {
obj->critterAP_weaponAmmoPid = pidArg.rawValue();
} else {
OpcodeInvalidArgs("set_weapon_ammo_pid");
}
}
static void __declspec(naked) set_weapon_ammo_pid() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
mov ecx, eax;
mov eax, ebp;
call interpretPopShort_;
mov esi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz end;
cmp si, VAR_TYPE_INT;
jnz end;
test eax, eax;
jz end;
mov [eax+0x40], ecx;
end:
popad;
retn;
_WRAP_OPCODE(set_weapon_ammo_pid2, 2, 0)
}
static void _stdcall get_weapon_ammo_count2() {
TGameObj* obj = opHandler.arg(0).asObject();
if (obj) {
opHandler.setReturn(obj->itemCharges);
} else {
OpcodeInvalidArgs("get_weapon_ammo_count");
opHandler.setReturn(0);
}
}
static void __declspec(naked) get_weapon_ammo_count() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz fail;
test eax, eax;
jz fail;
mov edx, [eax+0x3c];
jmp end;
fail:
xor edx, edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov eax, ebp;
mov edx, VAR_TYPE_INT;
call interpretPushShort_;
popad;
retn;
_WRAP_OPCODE(get_weapon_ammo_count2, 1, 1)
}
static void _stdcall set_weapon_ammo_count2() {
TGameObj* obj = opHandler.arg(0).asObject();
const ScriptValue &countArg = opHandler.arg(1);
if (obj && countArg.isInt()) {
obj->itemCharges = countArg.rawValue();
} else {
OpcodeInvalidArgs("set_weapon_ammo_count");
}
}
static void __declspec(naked) set_weapon_ammo_count() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
mov ecx, eax;
mov eax, ebp;
call interpretPopShort_;
mov esi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz end;
cmp si, VAR_TYPE_INT;
jnz end;
test eax, eax;
jz end;
mov [eax+0x3c], ecx;
end:
popad;
retn;
}
_WRAP_OPCODE(set_weapon_ammo_count2, 2, 0)
}
#define BLOCKING_TYPE_BLOCK (0)
@@ -741,7 +690,7 @@ static void sf_set_unique_id() {
opHandler.setReturn(id);
}
void sf_objects_in_radius() {
static void sf_objects_in_radius() {
const ScriptValue &tileArg = opHandler.arg(0),
&radiusArg = opHandler.arg(1),
&elevArg = opHandler.arg(2);
+36 -64
View File
@@ -573,34 +573,22 @@ static DWORD _stdcall ListAsArray(DWORD type) {
return id;
}
static void __declspec(naked) list_as_array() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz fail;
push eax;
call ListAsArray;
mov edx, eax;
jmp end;
fail:
xor edx, edx;
dec edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov eax, ebp;
mov edx, VAR_TYPE_INT;
call interpretPushShort_;
popad;
retn;
static void _stdcall list_as_array2() {
const ScriptValue &typeArg = opHandler.arg(0);
if (typeArg.isInt()) {
DWORD arrayId = ListAsArray(typeArg.rawValue());
opHandler.setReturn(arrayId);
} else {
OpcodeInvalidArgs("list_as_array");
opHandler.setReturn(-1);
}
}
static void __declspec(naked) list_as_array() {
_WRAP_OPCODE(list_as_array2, 1, 1)
}
static DWORD _stdcall ListBegin(DWORD type) {
std::vector<TGameObj*> vec = std::vector<TGameObj*>();
FillListVector(type, vec);
@@ -609,33 +597,21 @@ static DWORD _stdcall ListBegin(DWORD type) {
return listID;
}
static void __declspec(naked) list_begin() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz fail;
push eax;
call ListBegin;
mov edx, eax;
jmp end;
fail:
xor edx, edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov eax, ebp;
mov edx, VAR_TYPE_INT;
call interpretPushShort_;
popad;
retn;
static void _stdcall list_begin2() {
const ScriptValue &typeArg = opHandler.arg(0);
if (typeArg.isInt()) {
opHandler.setReturn(ListBegin(typeArg.rawValue()));
} else {
OpcodeInvalidArgs("list_begin");
opHandler.setReturn(0);
}
}
static void __declspec(naked) list_begin() {
_WRAP_OPCODE(list_begin2, 1, 1)
}
static TGameObj* _stdcall ListNext(sList* list) {
return (!list || list->pos == list->len) ? 0 : list->obj[list->pos++];
}
@@ -679,20 +655,16 @@ static void _stdcall ListEnd(DWORD id) {
}
}
static void __declspec(naked) list_end() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz end;
push eax;
call ListEnd;
end:
popad;
retn;
static void _stdcall list_end2() {
const ScriptValue &idArg = opHandler.arg(0);
if (idArg.isInt()) {
ListEnd(idArg.rawValue());
} else {
OpcodeInvalidArgs("list_end");
}
}
static void __declspec(naked) list_end() {
_WRAP_OPCODE(list_end2, 1, 0)
}
+54 -180
View File
@@ -89,118 +89,57 @@ static bool _stdcall FalloutStringCompare(const char* str1, const char* str2, lo
}
}
static DWORD _stdcall mystrlen(const char* str) {
return strlen(str);
}
static void _stdcall op_strlen2() {
const ScriptValue &strArg = opHandler.arg(0);
static void __declspec(naked) op_strlen() {
__asm {
pushad;
mov edi, eax;
call interpretPopShort_;
mov edx, eax;
mov eax, edi;
call interpretPopLong_; // string
cmp dx, VAR_TYPE_STR2;
je next;
cmp dx, VAR_TYPE_STR;
jne fail;
next:
mov ebx, eax;
mov eax, edi;
call interpretGetString_;
push eax;
call mystrlen;
jmp end;
fail:
xor eax, eax; // return 0
end:
mov edx, eax;
mov eax, edi;
call interpretPushLong_;
mov edx, VAR_TYPE_INT;
mov eax, edi;
call interpretPushShort_;
popad;
retn;
if (strArg.isString()) {
opHandler.setReturn(
static_cast<int>(strlen(strArg.strValue()))
);
} else {
OpcodeInvalidArgs("strlen");
opHandler.setReturn(0);
}
}
static int _stdcall str_to_int_internal(const char* str) {
return static_cast<int>(strtol(str, (char**)nullptr, 0)); // auto-determine radix
static void __declspec(naked) op_strlen() {
_WRAP_OPCODE(op_strlen2, 1, 1)
}
static DWORD _stdcall str_to_flt_internal(const char* str) {
float f = static_cast<float>(atof(str));
return *(DWORD*)&f;
static void _stdcall str_to_int2() {
const ScriptValue &strArg = opHandler.arg(0);
if (strArg.isString()) {
const char* str = strArg.strValue();
opHandler.setReturn(
static_cast<int>(strtol(str, (char**)nullptr, 0)) // auto-determine radix
);
} else {
OpcodeInvalidArgs("atoi");
opHandler.setReturn(0);
}
}
static void __declspec(naked) str_to_int() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ebp;
call interpretPopLong_;
cmp bx, VAR_TYPE_STR2;
jz str1;
cmp bx, VAR_TYPE_STR;
jnz fail;
str1:
mov edx, ebx;
mov ebx, eax;
mov eax, ebp;
call interpretGetString_;
push eax;
call str_to_int_internal;
mov edx, eax;
jmp end;
fail:
xor edx, edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov edx, VAR_TYPE_INT;
mov eax, ebp;
call interpretPushShort_;
popad;
retn;
_WRAP_OPCODE(str_to_int2, 1, 1)
}
static void _stdcall str_to_flt2() {
const ScriptValue &strArg = opHandler.arg(0);
if (strArg.isString()) {
const char* str = strArg.strValue();
opHandler.setReturn(
static_cast<float>(atof(str))
);
} else {
OpcodeInvalidArgs("atof");
opHandler.setReturn(0);
}
}
static void __declspec(naked) str_to_flt() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ebp;
call interpretPopLong_;
cmp bx, VAR_TYPE_STR2;
jz str1;
cmp bx, VAR_TYPE_STR;
jnz fail;
str1:
mov edx, ebx;
mov ebx, eax;
mov eax, ebp;
call interpretGetString_;
push eax;
call str_to_flt_internal;
mov edx, eax;
jmp end;
fail:
xor edx, edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov edx, VAR_TYPE_FLOAT;
mov eax, ebp;
call interpretPushShort_;
popad;
retn;
}
_WRAP_OPCODE(str_to_flt2, 1, 1)
}
static void _stdcall op_ord2() {
@@ -219,40 +158,12 @@ static void __declspec(naked) op_ord() {
_WRAP_OPCODE(op_ord2, 1, 1)
}
static DWORD _stdcall GetValueType(DWORD datatype) {
datatype &= 0xFFFF;
switch (datatype) {
case VAR_TYPE_STR:
case VAR_TYPE_STR2:
return DATATYPE_STR;
case VAR_TYPE_INT:
return DATATYPE_INT;
case VAR_TYPE_FLOAT:
return DATATYPE_FLOAT;
default:
return DATATYPE_NONE; // just in case
}
static void _stdcall op_typeof2() {
opHandler.setReturn(static_cast<int>(opHandler.arg(0).type()));
}
static void __declspec(naked) op_typeof() {
__asm {
pushad;
mov edi, eax;
call interpretPopShort_;
mov edx, eax;
mov eax, edi;
call interpretPopLong_; // call just in case (not used)
push edx;
call GetValueType;
mov edx, eax;
mov eax, edi;
call interpretPushLong_;
mov edx, VAR_TYPE_INT;
mov eax, edi;
call interpretPushShort_;
popad;
retn;
}
_WRAP_OPCODE(op_typeof2, 1, 1)
}
static int _stdcall StringSplit(const char* str, const char* split) {
@@ -287,59 +198,22 @@ static int _stdcall StringSplit(const char* str, const char* split) {
return id;
}
static void __declspec(naked) string_split() {
__asm {
pushad;
mov ebp, eax;
call interpretPopShort_;
mov ebx, eax;
mov eax, ebp;
call interpretPopLong_;
mov edi, eax;
mov eax, ebp;
call interpretPopShort_;
mov ecx, eax;
mov eax, ebp;
call interpretPopLong_;
mov esi, eax;
cmp bx, VAR_TYPE_STR2;
jz str1;
cmp bx, VAR_TYPE_STR;
jnz fail;
str1:
cmp cx, VAR_TYPE_STR2;
jz str2;
cmp cx, VAR_TYPE_STR;
jnz fail;
str2:
mov eax, ebp;
mov edx, ebx;
mov ebx, edi;
call interpretGetString_;
mov edi, eax;
mov eax, ebp;
mov edx, ecx;
mov ebx, esi;
call interpretGetString_;
push edi;
push eax;
call StringSplit;
mov edx, eax;
jmp end;
fail:
xor edx, edx;
dec edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov edx, VAR_TYPE_INT;
mov eax, ebp;
call interpretPushShort_;
popad;
retn;
static void _stdcall string_split2() {
const ScriptValue &strArg = opHandler.arg(0),
&splitArg = opHandler.arg(1);
if (strArg.isString() && splitArg.isString()) {
opHandler.setReturn(StringSplit(strArg.strValue(), splitArg.strValue()));
} else {
OpcodeInvalidArgs("string_split");
opHandler.setReturn(-1);
}
}
static void __declspec(naked) string_split() {
_WRAP_OPCODE(string_split2, 2, 1)
}
static char* _stdcall SubString(const char* str, int startPos, int length) {
int len = strlen(str);