Added DivisionOperatorFix option for signed integer division (#278)

* it changes the behavior of vanilla division operator to use signed
integer division. Before it used signed division for floats but
unsigned for integers.

Added a new "div" operator for unsigned integer division.
Moved mathematical script functions from ScriptUtils.hpp to new MathOps.
Added include guard to sfall.h and main.h in modders pack.
This commit is contained in:
NovaRain
2020-02-02 21:49:54 +08:00
parent 1354467059
commit 21bf1056ac
14 changed files with 435 additions and 358 deletions
+3
View File
@@ -568,6 +568,9 @@ StartGDialogFix=0
;attacker_results - unused, must be 0 or not equal to the target_results argument when specifying result flags for the target ;attacker_results - unused, must be 0 or not equal to the target_results argument when specifying result flags for the target
AttackComplexFix=0 AttackComplexFix=0
;Set to 1 to fix the issue with the division operator treating negative integers as unsigned
DivisionOperatorFix=1
;Set to 1 to enable the balanced bullet distribution formula for burst attacks ;Set to 1 to enable the balanced bullet distribution formula for burst attacks
ComputeSprayMod=0 ComputeSprayMod=0
@@ -1,3 +1,5 @@
#ifndef MAIN_H
#define MAIN_H
#include "..\scripting\headers\sfall.h" #include "..\scripting\headers\sfall.h"
#include "..\scripting\headers\define_lite.h" #include "..\scripting\headers\define_lite.h"
@@ -71,3 +73,5 @@ end
procedure InitConfigs begin procedure InitConfigs begin
translationIni := GetIniConfigStr("Main", "TranslationsINI", "Translations.ini", "ddraw.ini"); translationIni := GetIniConfigStr("Main", "TranslationsINI", "Translations.ini", "ddraw.ini");
end end
#endif
@@ -344,6 +344,7 @@ There are several changes in this version of sslc which may result in problems f
- fixed compiler giving "assignment operator expected" error when a variable-like macro is not being defined properly - fixed compiler giving "assignment operator expected" error when a variable-like macro is not being defined properly
- added new logical operators "AndAlso", "OrElse" for short-circuit evaluation of logical expressions - added new logical operators "AndAlso", "OrElse" for short-circuit evaluation of logical expressions
- added an alternative (C/Java-style) assignment operator "=" - added an alternative (C/Java-style) assignment operator "="
- added support for new "div" operator (unsigned integer division)
> sfall 4.2.2 > sfall 4.2.2
- added support for new opcode "reg_anim_callback" - added support for new opcode "reg_anim_callback"
+3 -3
View File
@@ -10,10 +10,10 @@
#define below(a, b) (unsigned_comp(a, b) < 0) #define below(a, b) (unsigned_comp(a, b) < 0)
#define below_equal(a, b) (unsigned_comp(a, b) <= 0) #define below_equal(a, b) (unsigned_comp(a, b) <= 0)
procedure unsigned_comp(variable a, variable b) begin // for sfall 4.2.3/3.8.23
pure procedure unsigned_comp(variable a, variable b) begin
if ((a bwxor b) == 0) then return 0; // a == b if ((a bwxor b) == 0) then return 0; // a == b
if (b == 0) then return 1; return 1 if ((b == 0) orElse a div b) else -1;
return 1 if (a / b) else -1;
end end
#define MAX(x, y) ((x > y) * x + (x <= y) * y) #define MAX(x, y) ((x > y) * x + (x <= y) * y)
+5
View File
@@ -1,3 +1,6 @@
#ifndef SFALL_H
#define SFALL_H
//Recognised modes for set_shader_mode and get_game_mode //Recognised modes for set_shader_mode and get_game_mode
#define WORLDMAP (0x1) #define WORLDMAP (0x1)
#define DIALOG (0x4) #define DIALOG (0x4)
@@ -305,3 +308,5 @@
#define unjam_lock(obj) sfall_func1("unjam_lock", obj) #define unjam_lock(obj) sfall_func1("unjam_lock", obj)
#define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1) #define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1)
#define unwield_slot(critter, slot) sfall_func2("unwield_slot", critter, slot) #define unwield_slot(critter, slot) sfall_func2("unwield_slot", critter, slot)
#endif
@@ -360,6 +360,8 @@
0x827d - void register_hook_proc_spec(int hook, procedure proc) 0x827d - void register_hook_proc_spec(int hook, procedure proc)
0x827e - void reg_anim_callback(procedure proc) 0x827e - void reg_anim_callback(procedure proc)
0x827f - div operator (unsigned integer division)
* These functions require AllowUnsafeScripting to be enabled in ddraw.ini * These functions require AllowUnsafeScripting to be enabled in ddraw.ini
+7 -1
View File
@@ -2488,7 +2488,7 @@ void BugFixesInit()
if (isDebug && (iniGetInt("Debugging", "BugFixes", 1, ddrawIniDef) == 0)) return; if (isDebug && (iniGetInt("Debugging", "BugFixes", 1, ddrawIniDef) == 0)) return;
#endif #endif
// Fix vanilla negate operator on float values // Fix vanilla negate operator for float values
MakeCall(0x46AB68, NegateFixHack); MakeCall(0x46AB68, NegateFixHack);
// Fix incorrect int-to-float conversion // Fix incorrect int-to-float conversion
// op_mult: // op_mult:
@@ -2497,6 +2497,12 @@ void BugFixesInit()
// op_div: // op_div:
SafeWrite16(0x46A566, 0x04DB); SafeWrite16(0x46A566, 0x04DB);
SafeWrite16(0x46A4E7, 0x04DB); SafeWrite16(0x46A4E7, 0x04DB);
// Fix for vanilla division operator treating negative integers as unsigned
if (GetConfigInt("Misc", "DivisionOperatorFix", 1)) {
dlog("Applying division operator fix.", DL_INIT);
SafeWrite32(0x46A51D, 0xFBF79990); // xor edx, edx; div ebx > cdq; idiv ebx
dlogr(" Done", DL_INIT);
}
//if (GetConfigInt("Misc", "SpecialUnarmedAttacksFix", 1)) { //if (GetConfigInt("Misc", "SpecialUnarmedAttacksFix", 1)) {
dlog("Applying Special Unarmed Attacks fix.", DL_INIT); dlog("Applying Special Unarmed Attacks fix.", DL_INIT);
+11 -9
View File
@@ -382,16 +382,17 @@ static void OpcodeInvalidArgs(const char* opcodeName) {
#include "ScriptOps\ScriptArrays.hpp" #include "ScriptOps\ScriptArrays.hpp"
#include "ScriptOps\ScriptUtils.hpp" #include "ScriptOps\ScriptUtils.hpp"
#include "ScriptOps\WorldmapOps.hpp"
#include "ScriptOps\PerksOp.hpp"
#include "ScriptOps\MemoryOp.hpp"
#include "ScriptOps\StatsOp.hpp"
#include "ScriptOps\InterfaceOp.hpp"
#include "ScriptOps\GraphicsOp.hpp"
#include "ScriptOps\FileSystemOps.hpp"
#include "ScriptOps\ObjectsOps.hpp"
#include "ScriptOps\AnimOps.hpp" #include "ScriptOps\AnimOps.hpp"
#include "ScriptOps\FileSystemOps.hpp"
#include "ScriptOps\GraphicsOp.hpp"
#include "ScriptOps\InterfaceOp.hpp"
#include "ScriptOps\MathOps.hpp"
#include "ScriptOps\MemoryOp.hpp"
#include "ScriptOps\MiscOps.hpp" #include "ScriptOps\MiscOps.hpp"
#include "ScriptOps\ObjectsOps.hpp"
#include "ScriptOps\PerksOp.hpp"
#include "ScriptOps\StatsOp.hpp"
#include "ScriptOps\WorldmapOps.hpp"
#include "ScriptOps\MetaruleOp.hpp" #include "ScriptOps\MetaruleOp.hpp"
/* /*
@@ -1636,7 +1637,7 @@ void ScriptExtenderInit() {
opcodes[0x260] = op_reg_anim_turn_towards; opcodes[0x260] = op_reg_anim_turn_towards;
opcodes[0x261] = op_explosions_metarule; opcodes[0x261] = op_explosions_metarule;
opcodes[0x262] = register_hook_proc; opcodes[0x262] = register_hook_proc;
opcodes[0x263] = funcPow; opcodes[0x263] = funcPow; // '^' operator
opcodes[0x264] = funcLog; opcodes[0x264] = funcLog;
opcodes[0x265] = funcExp; opcodes[0x265] = funcExp;
opcodes[0x266] = funcCeil; opcodes[0x266] = funcCeil;
@@ -1666,6 +1667,7 @@ void ScriptExtenderInit() {
opcodes[0x27d] = register_hook_proc_spec; opcodes[0x27d] = register_hook_proc_spec;
opcodes[0x27e] = op_reg_anim_callback; opcodes[0x27e] = op_reg_anim_callback;
opcodes[0x27f] = funcDiv; // div operator
InitOpcodeMetaTable(); InitOpcodeMetaTable();
InitMetaruleTable(); InitMetaruleTable();
+391
View File
@@ -0,0 +1,391 @@
/*
* sfall
* Copyright (C) 2008-2020 The sfall team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cmath>
#include "main.h"
#include "ScriptExtender.h"
static void _stdcall funcDiv2() {
const ScriptValue &dividend = opHandler.arg(0),
&divisor = opHandler.arg(1);
if (!dividend.isString() && !divisor.isString()) {
if (divisor.rawValue() == 0) {
opHandler.printOpcodeError("div - division by zero.");
return;
}
if (dividend.isFloat() || divisor.isFloat()) {
opHandler.setReturn(dividend.asFloat() / divisor.asFloat());
} else {
opHandler.setReturn(dividend.rawValue() / divisor.rawValue()); // unsigned division
}
} else {
OpcodeInvalidArgs("div");
opHandler.setReturn(0);
}
}
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 funcAbs2() {
const ScriptValue &value = opHandler.arg(0);
if (!value.isString()) {
if (value.isInt()) {
opHandler.setReturn(abs(static_cast<int>(value.rawValue())));
} else {
opHandler.setReturn(abs(value.asFloat()));
}
} else {
OpcodeInvalidArgs("abs");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcAbs() {
_WRAP_OPCODE(funcAbs2, 1, 1)
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
static void _stdcall funcPow2() {
const ScriptValue &base = opHandler.arg(0),
&power = opHandler.arg(1);
if (!base.isString() && !power.isString()) {
float result = 0.0;
if (power.isFloat())
result = pow(base.asFloat(), power.floatValue());
else
result = pow(base.asFloat(), static_cast<int>(power.rawValue()));
if (base.isInt() && power.isInt()) {
opHandler.setReturn(static_cast<int>(result));
} else {
opHandler.setReturn(result);
}
} else {
OpcodeInvalidArgs("power");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcPow() {
_WRAP_OPCODE(funcPow2, 2, 1)
}
static void _stdcall funcLog2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(log(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("log");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcLog() {
_WRAP_OPCODE(funcLog2, 1, 1)
}
static void _stdcall funcExp2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(exp(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("exponent");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcExp() {
_WRAP_OPCODE(funcExp2, 1, 1)
}
static void _stdcall funcCeil2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(static_cast<int>(ceil(floatArg.asFloat())));
} else {
OpcodeInvalidArgs("ceil");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcCeil() {
_WRAP_OPCODE(funcCeil2, 1, 1)
}
static void _stdcall funcRound2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
float arg = floatArg.asFloat();
int argI = static_cast<int>(arg);
float mod = arg - static_cast<float>(argI);
if (abs(mod) >= 0.5) argI += (mod > 0 ? 1 : -1);
opHandler.setReturn(argI);
} else {
OpcodeInvalidArgs("round");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcRound() {
_WRAP_OPCODE(funcRound2, 1, 1)
}
static void sf_floor2() {
const ScriptValue &valArg = opHandler.arg(0);
if (!valArg.isString()) {
opHandler.setReturn(static_cast<int>(floor(valArg.asFloat())));
} else {
OpcodeInvalidArgs("floor2");
opHandler.setReturn(0);
}
}
+3
View File
@@ -22,11 +22,14 @@
#include "AI.h" #include "AI.h"
#include "Combat.h" #include "Combat.h"
#include "Criticals.h"
#include "HeroAppearance.h" #include "HeroAppearance.h"
#include "Inventory.h"
#include "KillCounter.h" #include "KillCounter.h"
#include "Movies.h" #include "Movies.h"
#include "PartyControl.h" #include "PartyControl.h"
#include "ScriptExtender.h" #include "ScriptExtender.h"
#include "Stats.h"
/* /*
* Misc operators * Misc operators
+1
View File
@@ -20,6 +20,7 @@
#include "main.h" #include "main.h"
#include "Combat.h"
#include "Inventory.h" #include "Inventory.h"
#include "Objects.h" #include "Objects.h"
#include "PartyControl.h" #include "PartyControl.h"
-345
View File
@@ -18,12 +18,9 @@
#pragma once #pragma once
#include <cmath>
#include "main.h" #include "main.h"
#include "ScriptExtender.h" #include "ScriptExtender.h"
#include "ScriptArrays.hpp"
#include "Arrays.h" #include "Arrays.h"
#include "Message.h" #include "Message.h"
@@ -92,245 +89,6 @@ static bool _stdcall FalloutStringCompare(const char* str1, const char* str2, lo
} }
} }
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 funcAbs2() {
const ScriptValue &value = opHandler.arg(0);
if (!value.isString()) {
if (value.isInt()) {
opHandler.setReturn(abs((int)value.rawValue()));
} else {
opHandler.setReturn(abs(value.asFloat()));
}
} else {
OpcodeInvalidArgs("abs");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcAbs() {
_WRAP_OPCODE(funcAbs2, 1, 1)
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
static DWORD _stdcall mystrlen(const char* str) { static DWORD _stdcall mystrlen(const char* str) {
return strlen(str); return strlen(str);
} }
@@ -853,98 +611,6 @@ static void sf_string_format() {
} }
} }
static void funcPow2() {
const ScriptValue &base = opHandler.arg(0),
&power = opHandler.arg(1);
if (!base.isString() && !power.isString()) {
float result = 0.0;
if (power.isFloat())
result = pow(base.asFloat(), power.floatValue());
else
result = pow(base.asFloat(), (int)power.rawValue());
if (base.isInt() && power.isInt()) {
opHandler.setReturn(static_cast<int>(result));
} else {
opHandler.setReturn(result);
}
} else {
OpcodeInvalidArgs("power");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcPow() {
_WRAP_OPCODE(funcPow2, 2, 1)
}
static void funcLog2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(log(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("log");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcLog() {
_WRAP_OPCODE(funcLog2, 1, 1)
}
static void funcExp2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(exp(floatArg.asFloat()));
} else {
OpcodeInvalidArgs("exponent");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcExp() {
_WRAP_OPCODE(funcExp2, 1, 1)
}
static void funcCeil2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
opHandler.setReturn(static_cast<int>(ceil(floatArg.asFloat())));
} else {
OpcodeInvalidArgs("ceil");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcCeil() {
_WRAP_OPCODE(funcCeil2, 1, 1)
}
static void funcRound2() {
const ScriptValue &floatArg = opHandler.arg(0);
if (!floatArg.isString()) {
float arg = floatArg.asFloat();
int argI = static_cast<int>(arg);
float mod = arg - static_cast<float>(argI);
if (abs(mod) >= 0.5) {
argI += (mod > 0 ? 1 : -1);
}
opHandler.setReturn(argI);
} else {
OpcodeInvalidArgs("round");
opHandler.setReturn(0);
}
}
static void __declspec(naked) funcRound() {
_WRAP_OPCODE(funcRound2, 1, 1)
}
static void _stdcall op_message_str_game2() { static void _stdcall op_message_str_game2() {
const char* msg = nullptr; const char* msg = nullptr;
const ScriptValue &fileIdArg = opHandler.arg(0), const ScriptValue &fileIdArg = opHandler.arg(0),
@@ -977,17 +643,6 @@ static void __declspec(naked) op_message_str_game() {
_WRAP_OPCODE(op_message_str_game2, 2, 1) _WRAP_OPCODE(op_message_str_game2, 2, 1)
} }
static void sf_floor2() {
const ScriptValue &valArg = opHandler.arg(0);
if (!valArg.isString()) {
opHandler.setReturn(static_cast<int>(floor(valArg.asFloat())));
} else {
OpcodeInvalidArgs("floor2");
opHandler.setReturn(0);
}
}
static void sf_get_text_width() { static void sf_get_text_width() {
const ScriptValue &textArg = opHandler.arg(0); const ScriptValue &textArg = opHandler.arg(0);
+1
View File
@@ -322,6 +322,7 @@
<ClInclude Include="ScriptOps\FileSystemOps.hpp" /> <ClInclude Include="ScriptOps\FileSystemOps.hpp" />
<ClInclude Include="ScriptOps\GraphicsOp.hpp" /> <ClInclude Include="ScriptOps\GraphicsOp.hpp" />
<ClInclude Include="ScriptOps\InterfaceOp.hpp" /> <ClInclude Include="ScriptOps\InterfaceOp.hpp" />
<ClInclude Include="ScriptOps\MathOps.hpp" />
<ClInclude Include="ScriptOps\MemoryOp.hpp" /> <ClInclude Include="ScriptOps\MemoryOp.hpp" />
<ClInclude Include="ScriptOps\MetaruleOp.hpp" /> <ClInclude Include="ScriptOps\MetaruleOp.hpp" />
<ClInclude Include="ScriptOps\MiscOps.hpp" /> <ClInclude Include="ScriptOps\MiscOps.hpp" />
+3
View File
@@ -214,6 +214,9 @@
<ClInclude Include="Interface.h"> <ClInclude Include="Interface.h">
<Filter>Headers</Filter> <Filter>Headers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ScriptOps\MathOps.hpp">
<Filter>Headers\ScriptOps</Filter>
</ClInclude>
<ClInclude Include="stdafx.h"> <ClInclude Include="stdafx.h">
<Filter>Headers</Filter> <Filter>Headers</Filter>
</ClInclude> </ClInclude>