diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 910ce848..a1e896e6 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -1,5 +1,5 @@ ;sfall configuration settings -;v4.1.4 +;v4.1.5 [Main] ;Change to 1 if you want to use command line args to tell sfall to use another ini file. diff --git a/sfall/Modules/ScriptExtender.cpp b/sfall/Modules/ScriptExtender.cpp index d0b22695..ba765369 100644 --- a/sfall/Modules/ScriptExtender.cpp +++ b/sfall/Modules/ScriptExtender.cpp @@ -351,18 +351,19 @@ static void SetGlobalVarInternal(__int64 var, int val) { } } -void _stdcall SetGlobalVarInt(DWORD var, int val) { +void SetGlobalVarInt(DWORD var, int val) { SetGlobalVarInternal(var, val); } -void _stdcall SetGlobalVar(const char* var, int val) { +long SetGlobalVar(const char* var, int val) { if (strlen(var) != 8) { - return; + return -1; } SetGlobalVarInternal(*(__int64*)var, val); + return 0; } -static DWORD GetGlobalVarInternal(__int64 val) { +long GetGlobalVarInternal(__int64 val) { glob_citr itr = globalVars.find(val); if (itr == globalVars.end()) { return 0; @@ -371,14 +372,14 @@ static DWORD GetGlobalVarInternal(__int64 val) { } } -DWORD _stdcall GetGlobalVar(const char* var) { +long GetGlobalVar(const char* var) { if (strlen(var) != 8) { return 0; } return GetGlobalVarInternal(*(__int64*)var); } -DWORD _stdcall GetGlobalVarInt(DWORD var) { +long GetGlobalVarInt(DWORD var) { return GetGlobalVarInternal(var); } diff --git a/sfall/Modules/ScriptExtender.h b/sfall/Modules/ScriptExtender.h index 0ac7b620..cca71031 100644 --- a/sfall/Modules/ScriptExtender.h +++ b/sfall/Modules/ScriptExtender.h @@ -62,16 +62,14 @@ int GetNumGlobals(); void GetGlobals(GlobalVar* globals); void SetGlobals(GlobalVar* globals); -void _stdcall SetGlobalVar(const char* var, int val); -void _stdcall SetGlobalVarInt(DWORD var, int val); -DWORD _stdcall GetGlobalVar(const char* var); -DWORD _stdcall GetGlobalVarInt(DWORD var); +long SetGlobalVar(const char* var, int val); +void SetGlobalVarInt(DWORD var, int val); +long GetGlobalVar(const char* var); +long GetGlobalVarInt(DWORD var); +long GetGlobalVarInternal(__int64 val); void _stdcall SetSelfObject(fo::Program* script, fo::GameObject* obj); -void SetAppearanceGlobals(int race, int style); -void GetAppearanceGlobals(int *race, int *style); - void _stdcall RegAnimCombatCheck(DWORD newValue); bool _stdcall ScriptHasLoaded(fo::Program* script); diff --git a/sfall/Modules/Scripting/Handlers/Core.cpp b/sfall/Modules/Scripting/Handlers/Core.cpp index af7e31f9..49b92c76 100644 --- a/sfall/Modules/Scripting/Handlers/Core.cpp +++ b/sfall/Modules/Scripting/Handlers/Core.cpp @@ -96,140 +96,41 @@ void __declspec(naked) op_available_global_script_types() { } } -void __declspec(naked) op_set_sfall_global() { - __asm { - push ebx; - push ecx; - push edx; - push edi; - push esi; - mov edi, eax; - call fo::funcoffs::interpretPopShort_; - mov eax, edi; - call fo::funcoffs::interpretPopLong_; - mov esi, eax; - mov eax, edi; - call fo::funcoffs::interpretPopShort_; - mov edx, eax; - mov eax, edi; - call fo::funcoffs::interpretPopLong_; - cmp dx, VAR_TYPE_STR2; - jz next; - cmp dx, VAR_TYPE_STR; - jz next; - cmp dx, VAR_TYPE_INT; - jnz end; - push esi; - push eax; - call SetGlobalVarInt; - jmp end; -next: - mov ebx, eax; - mov eax, edi; - call fo::funcoffs::interpretGetString_; - push esi; - push eax; - call SetGlobalVar; -end: - pop esi; - pop edi; - pop edx; - pop ecx; - pop ebx; - retn; +void sf_set_sfall_global(OpcodeContext& ctx) { + if (ctx.arg(0).isString()) { + if (SetGlobalVar(ctx.arg(0).String(), ctx.arg(1).rawValue())) { + ctx.printOpcodeError("set_sfall_global() - The name of the global variable must consist of 8 characters."); + } + } else { + SetGlobalVarInt(ctx.arg(0).rawValue(), ctx.arg(1).rawValue()); } } -void __declspec(naked) op_get_sfall_global_int() { - __asm { - push ebx; - push ecx; - push edx; - push edi; - push esi; - xor edx, edx; - mov edi, eax; - call fo::funcoffs::interpretPopShort_; - mov esi, eax; - mov eax, edi; - call fo::funcoffs::interpretPopLong_; - cmp si, VAR_TYPE_STR2; - jz next; - cmp si, VAR_TYPE_STR; - jz next; - cmp si, VAR_TYPE_INT; - jnz end; - push eax; - call GetGlobalVarInt; - mov edx, eax; - jmp end; -next: - mov edx, esi; - mov ebx, eax; - mov eax, edi; - call fo::funcoffs::interpretGetString_; - push eax; - call GetGlobalVar; - mov edx, eax; -end: - mov eax, edi; - call fo::funcoffs::interpretPushLong_; - mov edx, VAR_TYPE_INT; - mov eax, edi; - call fo::funcoffs::interpretPushShort_; - pop esi; - pop edi; - pop edx; - pop ecx; - pop ebx; - retn; +static long GetGlobalVarNameString(OpcodeContext& ctx) { + const char* var = ctx.arg(0).String(); + if (strlen(var) != 8) { + ctx.printOpcodeError("get_sfall_global() - The name of the global variable must consist of 8 characters."); + return 0; } + return GetGlobalVarInternal(*(__int64*)var); } -void __declspec(naked) op_get_sfall_global_float() { - __asm { - push ebx; - push ecx; - push edx; - push edi; - push esi; - xor edx, edx; - mov edi, eax; - call fo::funcoffs::interpretPopShort_; - mov esi, eax; - mov eax, edi; - call fo::funcoffs::interpretPopLong_; - cmp si, VAR_TYPE_STR2; - jz next; - cmp si, VAR_TYPE_STR; - jz next; - cmp si, VAR_TYPE_INT; - jnz end; - push eax; - call GetGlobalVarInt; - mov edx, eax; - jmp end; -next: - mov edx, esi; - mov ebx, eax; - mov eax, edi; - call fo::funcoffs::interpretGetString_; - push eax; - call GetGlobalVar; - mov edx, eax; -end: - mov eax, edi; - call fo::funcoffs::interpretPushLong_; - mov edx, VAR_TYPE_FLOAT; - mov eax, edi; - call fo::funcoffs::interpretPushShort_; - pop esi; - pop edi; - pop edx; - pop ecx; - pop ebx; - retn; +static void GetGlobalVar(OpcodeContext& ctx, DataType type) { + long result; + if (ctx.arg(0).isString()) { + result = GetGlobalVarNameString(ctx); + } else { + result = GetGlobalVarInt(ctx.arg(0).rawValue()); } + ctx.setReturn(result, type); +} + +void sf_get_sfall_global_int(OpcodeContext& ctx) { + GetGlobalVar(ctx, DataType::INT); +} + +void sf_get_sfall_global_float(OpcodeContext& ctx) { + GetGlobalVar(ctx, DataType::FLOAT); } void __declspec(naked) op_get_sfall_arg() { diff --git a/sfall/Modules/Scripting/Handlers/Core.h b/sfall/Modules/Scripting/Handlers/Core.h index bc3fcd7c..eb1ead6e 100644 --- a/sfall/Modules/Scripting/Handlers/Core.h +++ b/sfall/Modules/Scripting/Handlers/Core.h @@ -33,11 +33,11 @@ void __declspec() op_set_global_script_type(); void __declspec() op_available_global_script_types(); -void __declspec() op_set_sfall_global(); +void sf_set_sfall_global(OpcodeContext&); -void __declspec() op_get_sfall_global_int(); +void sf_get_sfall_global_int(OpcodeContext&); -void __declspec() op_get_sfall_global_float(); +void sf_get_sfall_global_float(OpcodeContext&); void __declspec() op_get_sfall_arg(); diff --git a/sfall/Modules/Scripting/Opcodes.cpp b/sfall/Modules/Scripting/Opcodes.cpp index 4d7de7a8..bfe4f87e 100644 --- a/sfall/Modules/Scripting/Opcodes.cpp +++ b/sfall/Modules/Scripting/Opcodes.cpp @@ -64,6 +64,11 @@ typedef std::unordered_map OpcodeInfoMapType; // } static SfallOpcodeInfo opcodeInfoArray[] = { {0x16c, "key_pressed", sf_key_pressed, 1, true}, + + {0x19d, "set_sfall_global", sf_set_sfall_global, 2, false, {ARG_INTSTR, ARG_NUMBER}}, + {0x19e, "get_sfall_global_int", sf_get_sfall_global_int, 1, true, {ARG_INTSTR}}, + {0x19f, "get_sfall_global_float", sf_get_sfall_global_float, 1, true, {ARG_INTSTR}}, + {0x1dc, "show_iface_tag", sf_show_iface_tag, 1, false, {ARG_INT}}, {0x1dd, "hide_iface_tag", sf_hide_iface_tag, 1, false, {ARG_INT}}, {0x1de, "is_iface_tag_active", sf_is_iface_tag_active, 1, true, {ARG_INT}}, @@ -295,9 +300,6 @@ void InitNewOpcodes() { opcodes[0x19a] = op_remove_attacker_knockback; opcodes[0x19b] = op_set_global_script_type; opcodes[0x19c] = op_available_global_script_types; - opcodes[0x19d] = op_set_sfall_global; - opcodes[0x19e] = op_get_sfall_global_int; - opcodes[0x19f] = op_get_sfall_global_float; opcodes[0x1a0] = op_set_pickpocket_max; opcodes[0x1a1] = op_set_hit_chance_max; opcodes[0x1a2] = op_set_skill_max; diff --git a/sfall/Modules/Scripting/ScriptValue.cpp b/sfall/Modules/Scripting/ScriptValue.cpp index 6c084e21..f31690a6 100644 --- a/sfall/Modules/Scripting/ScriptValue.cpp +++ b/sfall/Modules/Scripting/ScriptValue.cpp @@ -89,10 +89,10 @@ unsigned long ScriptValue::rawValue() const { int ScriptValue::asInt() const { switch (_type) { - case DataType::FLOAT: - return static_cast(_val.f); case DataType::INT: return _val.i; + case DataType::FLOAT: + return static_cast(_val.f); default: return 0; } @@ -100,10 +100,10 @@ int ScriptValue::asInt() const { bool ScriptValue::asBool() const { switch (_type) { - case DataType::FLOAT: - return static_cast(_val.f) != 0; case DataType::INT: return _val.i != 0; + case DataType::FLOAT: + return static_cast(_val.f) != 0; default: return true; } @@ -132,6 +132,10 @@ fo::GameObject* ScriptValue::asObject() const { : nullptr; } +const char* ScriptValue::String() const { + return _val.str; +} + DataType ScriptValue::type() const { return _type; } diff --git a/sfall/Modules/Scripting/ScriptValue.h b/sfall/Modules/Scripting/ScriptValue.h index 298ebf71..1b63fcfa 100644 --- a/sfall/Modules/Scripting/ScriptValue.h +++ b/sfall/Modules/Scripting/ScriptValue.h @@ -68,6 +68,7 @@ public: // returns string value or empty string if value is not string type const char* asString() const; + const char* String() const; // returns value as object pointer or nullptr if value is not integer fo::GameObject* asObject() const; diff --git a/sfall/version.h b/sfall/version.h index 650ebf85..d676a1f2 100644 --- a/sfall/version.h +++ b/sfall/version.h @@ -24,10 +24,10 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 1 -#define VERSION_BUILD 4 -#define VERSION_REV 1 +#define VERSION_BUILD 5 +#define VERSION_REV 0 -#define VERSION_STRING "4.1.4.1" +#define VERSION_STRING "4.1.5" #define CHECK_VAL (4)