From b5306406b3a34262dd0517be6c66595441f2b0b0 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Fri, 26 Oct 2018 06:51:52 +0800 Subject: [PATCH] Replaced some __cdecl calling conventions with __fastcall. (from Mr.Stalin - Reason: The compiler can use the arguments for its own purposes, which can spoil the stored value on the stack.) Added extra notes for some options to ddraw.ini. --- artifacts/ddraw.ini | 8 +++++--- sfall/AI.cpp | 17 ++++++++++------- sfall/QuestList.cpp | 16 +++++++--------- sfall/ScriptExtender.cpp | 7 ++++--- sfall/main.cpp | 28 +++++++++++++--------------- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 252c14da..62c86ce3 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -374,8 +374,8 @@ EnableHeroAppearanceMod=0 ;Set to 1 to skip the 3 opening movies SkipOpeningMovies=0 -;Causes NPCs who complete their combat turn with ap left over will try and find other ways to spend it. -;Only NPCs with ap left equal to or greater than the value given here will be considered. +;Causes NPCs who complete their combat turn with AP left over will try and find other ways to spend it. +;Only NPCs with AP left equal to or greater than the value given here will be considered. ;Set to 0 to disable NPCsTryToSpendExtraAP=0 @@ -493,6 +493,7 @@ BoostScriptDialogLimit=0 ;Set the mode to 0 to disable the size check, 1 to apply to the PC only, 2 to apply to the PC and party members, or 3 to apply to all critters ;Only the PC uses CritterInvSizeLimit. Other critters will use the unused stat (STAT_unused = 10) or have the size limit of 100 if the stat is not set ;Add 4 to the mode to limit the weight check to used items only +;You can use line number 542/543 in proto.msg and line number 35 in inventry.msg to set up custom messages for item size CritterInvSizeLimitMode=0 CritterInvSizeLimit=100 @@ -522,7 +523,8 @@ SuperStimExploitFix=0 InventoryApCost=4 QuickPocketsApCostReduction=2 -;Set to 1 to allow objects seeing through other objects with their ShootThru flag set +;Set to 1 to allow objects seeing through other objects that have their ShootThru flag set +;Note that enabling this option can cause unexpected NPC behavior in some situations ObjCanSeeObj_ShootThru_Fix=0 ;Set to 1 to fix the broken obj_can_hear_obj script function diff --git a/sfall/AI.cpp b/sfall/AI.cpp index ad8f7e6a..a4364eba 100644 --- a/sfall/AI.cpp +++ b/sfall/AI.cpp @@ -40,19 +40,22 @@ DWORD _stdcall AIGetLastTarget(DWORD source) { else return itr->second; } -static void _stdcall CombatAttackHook(DWORD source, DWORD target) { - sources[target]=source; - targets[source]=target; +static void __fastcall CombatAttackHook(DWORD source, DWORD target) { + sources[target] = source; + targets[source] = target; } static void __declspec(naked) combat_attack_hook() { _asm { - pushad; + push ecx; push edx; push eax; - call CombatAttackHook; - popad; - jmp combat_attack_; + mov ecx, eax; // source + call CombatAttackHook; // edx - target + pop eax; + pop edx; + pop ecx; + jmp combat_attack_; } } diff --git a/sfall/QuestList.cpp b/sfall/QuestList.cpp index 0b3564d9..4800810d 100644 --- a/sfall/QuestList.cpp +++ b/sfall/QuestList.cpp @@ -94,7 +94,6 @@ end: } static void ResetPageValues() { - if (total_quests_pages > 0) pageQuest.resize(1); pageFlag = false; @@ -174,8 +173,7 @@ static void AddPage(int lines) { } // Print quests page text -static long __cdecl QuestsPrint(const char* text, int width, DWORD* buf, BYTE* count) { - +static long __fastcall QuestsPrint(const char* text, int width, DWORD* buf, BYTE* count) { look_quests++; // quests counter if (outRangeFlag) { @@ -222,10 +220,11 @@ static void __declspec(naked) PipStatus_hack_print() { push ecx; push ebx; push edx; - push eax; - call QuestsPrint; - add esp, 4; // eax - pop edx; // restore reg. and align stack for __cdecl call + push ecx; // count + push ebx; // buf + mov ecx, eax; // text + call QuestsPrint; // edx - width + pop edx; pop ebx; pop ecx; cmp eax, 0; @@ -242,8 +241,7 @@ jbreak: static char bufPage[16]; static const char* format = "%s %d %s %d"; -static void __declspec(naked) PrintPages() -{ +static void __declspec(naked) PrintPages() { __asm { // total pages mov eax, total_quests_pages; diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index a20c9dc6..98ada738 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -1051,7 +1051,7 @@ static void __declspec(naked) ExecMapScriptsHack() { } } -static DWORD __cdecl GetGlobalExportedVarPtr(const char* name) { +static DWORD __fastcall GetGlobalExportedVarPtr(const char* name) { std::string str(name); ExportedVarsMap::iterator it = globalExportedVars.find(str); //dlog_f("\n Trying to find exported var %s... ", DL_MAIN, name); @@ -1079,8 +1079,9 @@ static void __stdcall CreateGlobalExportedVar(DWORD scr, const char* name) { static void __declspec(naked) Export_FetchOrStore_FindVar_Hook() { __asm { push ecx; - push edx; // char* varName - call GetGlobalExportedVarPtr; //_cdecl + push edx; + mov ecx, edx; // varName + call GetGlobalExportedVarPtr; pop edx; pop ecx; test eax, eax diff --git a/sfall/main.cpp b/sfall/main.cpp index ed719166..2be81ed7 100644 --- a/sfall/main.cpp +++ b/sfall/main.cpp @@ -658,21 +658,19 @@ fail: } } -static void __declspec(naked) objCanSeeObj_ShootThru_Fix() {//(EAX *objStruct, EDX hexNum1, EBX hexNum2, ECX ?, stack1 **ret_objStruct, stack2 flags) +static void __declspec(naked) op_obj_can_see_obj_hook() { // (EAX *objStruct, EDX hexNum1, EBX hexNum2, ECX ?, stack1 **ret_objStruct, stack2 flags) __asm { - push esi - push edi - - push obj_shoot_blocking_at_ //arg3 check hex objects func pointer - mov esi, 0x20//arg2 flags, 0x20 = check shootthru - push esi - mov edi, dword ptr ss : [esp + 0x14] //arg1 **ret_objStruct - push edi - call make_straight_path_func_;//(EAX *objStruct, EDX hexNum1, EBX hexNum2, ECX ?, stack1 **ret_objStruct, stack2 flags, stack3 *check_hex_objs_func) - - pop edi - pop esi - ret 0x8 + push esi; + push edi; + push obj_shoot_blocking_at_; // arg3 check hex objects func pointer + mov esi, 0x20; // arg2 flags, 0x20 = check shootthru + push esi; + mov edi, dword ptr ss:[esp + 0x14]; // arg1 **ret_objStruct + push edi; + call make_straight_path_func_; // (EAX *objStruct, EDX hexNum1, EBX hexNum2, ECX ?, stack1 **ret_objStruct, stack2 flags, stack3 *check_hex_objs_func) + pop edi; + pop esi; + retn 8; } } @@ -1438,7 +1436,7 @@ static void DllMain2() { if (GetPrivateProfileIntA("Misc", "ObjCanSeeObj_ShootThru_Fix", 0, ini)) { dlog("Applying ObjCanSeeObj ShootThru Fix.", DL_INIT); - SafeWrite32(0x456BC7, (DWORD)&objCanSeeObj_ShootThru_Fix - 0x456BCB); + HookCall(0x456BC6, &op_obj_can_see_obj_hook); dlogr(" Done", DL_INIT); }