Changed the behavior of saving/restoring hook arguments

(no need to specify the number of args when executing a nested hook)
Reverted the change of argCount in some hooks.
Disabled an obsolete fix for MultiHexPathingFix.
Simplified the code of draw_image/draw_image_scaled script functions.
This commit is contained in:
NovaRain
2020-09-25 00:12:22 +08:00
parent b195a8ab02
commit 52f42af913
3 changed files with 42 additions and 64 deletions
+14 -13
View File
@@ -916,17 +916,17 @@ fix:
}
// Haenlomal: Check path to critter for attack
static void __declspec(naked) MultiHexFix() {
__asm {
xor ecx, ecx; // argument value for make_path_func: ecx=0 (rotation data arg)
test [ebx + flags + 1], 0x08; // is target multihex?
mov ebx, [ebx + tile]; // argument value for make_path_func: target's tilenum (end_tile)
je end; // skip if not multihex
inc ebx; // otherwise, increase tilenum by 1
end:
retn; // call make_path_func (at 0x429024, 0x429175)
}
}
//static void __declspec(naked) MultiHexFix() {
// __asm {
// xor ecx, ecx; // argument value for make_path_func: ecx=0 (rotation data arg)
// test [ebx + flags + 1], 0x08; // is target multihex?
// mov ebx, [ebx + tile]; // argument value for make_path_func: target's tilenum (end_tile)
// je end; // skip if not multihex
// inc ebx; // otherwise, increase tilenum by 1
//end:
// retn; // call make_path_func (at 0x429024, 0x429175)
// }
//}
static void __declspec(naked) MultiHexRetargetTileFix() {
__asm {
@@ -3044,8 +3044,9 @@ void BugFixesInit()
//if (GetConfigInt("Misc", "MultiHexPathingFix", 1)) {
dlog("Applying MultiHex Pathing Fix.", DL_INIT);
HookCall(0x416144, make_path_func_hook); // Fix for building the path to the central hex of a multihex object
const DWORD multiHexFixAddr[] = {0x42901F, 0x429170};
MakeCalls(MultiHexFix, multiHexFixAddr);
//const DWORD multiHexFixAddr[] = {0x42901F, 0x429170};
//MakeCalls(MultiHexFix, multiHexFixAddr); // obsolete fix
// Fix for multihex critters moving too close and overlapping their targets in combat
MakeCall(0x42A14F, MultiHexCombatRunFix, 1);
MakeCall(0x42A178, MultiHexCombatMoveFix, 1);
+13 -14
View File
@@ -86,8 +86,8 @@ static void __stdcall BeginHook() {
savedArgs[cDepth].cArg = cArg; // current count of taken arguments
savedArgs[cDepth].cRet = cRet; // number of return values for the current hook
savedArgs[cDepth].cRetTmp = cRetTmp;
memcpy(&savedArgs[cDepth].oldArgs, args, argCount * sizeof(DWORD)); // values of the arguments
if (cRet) memcpy(&savedArgs[cDepth].oldRets, rets, cRet * sizeof(DWORD)); // return values
std::memcpy(&savedArgs[cDepth].oldArgs, args, maxArgs * sizeof(DWORD)); // values of the arguments
if (cRet) std::memcpy(&savedArgs[cDepth].oldRets, rets, maxRets * sizeof(DWORD)); // return values
//devlog_f("\nSaved cArgs/cRet: %d / %d(%d)\n", DL_HOOK, savedArgs[cDepth].argCount, savedArgs[cDepth].cRet, cRetTmp);
//for (unsigned int i = 0; i < maxArgs; i++) {
@@ -149,8 +149,8 @@ static void __stdcall EndHook() {
cArg = savedArgs[cDepth].cArg;
cRet = savedArgs[cDepth].cRet;
cRetTmp = savedArgs[cDepth].cRetTmp; // also restore current count of the number of return values
memcpy(args, &savedArgs[cDepth].oldArgs, argCount * sizeof(DWORD));
if (cRet) memcpy(rets, &savedArgs[cDepth].oldRets, cRet * sizeof(DWORD));
std::memcpy(args, &savedArgs[cDepth].oldArgs, maxArgs * sizeof(DWORD));
if (cRet) std::memcpy(rets, &savedArgs[cDepth].oldRets, maxRets * sizeof(DWORD));
//devlog_f("Restored cArgs/cRet: %d / %d(%d)\n", DL_HOOK, argCount, cRet, cRetTmp);
//for (unsigned int i = 0; i < maxArgs; i++) {
@@ -166,7 +166,6 @@ static void __stdcall EndHook() {
static void __declspec(naked) ToHitHook() {
__asm {
HookBegin;
mov argCount, 8;
mov args[4], eax; // attacker
mov args[8], ebx; // target
mov args[12], ecx; // body part
@@ -182,6 +181,7 @@ static void __declspec(naked) ToHitHook() {
mov args[0], eax;
pushadc;
}
argCount = 8;
args[7] = Combat_determineHitChance;
RunHookScript(HOOK_TOHIT);
@@ -259,7 +259,6 @@ long __fastcall sf_item_w_mp_cost(TGameObj* source, long hitMode, long isCalled)
static void __declspec(naked) CalcApCostHook() {
__asm {
HookBegin;
mov argCount, 4;
mov args[0], eax;
mov args[4], edx;
mov args[8], ebx;
@@ -268,6 +267,7 @@ static void __declspec(naked) CalcApCostHook() {
pushad;
}
argCount = 4;
RunHookScript(HOOK_CALCAPCOST);
__asm {
@@ -702,7 +702,6 @@ static void __declspec(naked) OverrideCost_BarterPriceHook() {
static void __declspec(naked) MoveCostHook() {
__asm {
HookBegin;
mov argCount, 3;
mov args[0], eax;
mov args[4], edx;
call critter_compute_ap_from_distance_;
@@ -710,6 +709,7 @@ static void __declspec(naked) MoveCostHook() {
pushadc;
}
argCount = 3;
RunHookScript(HOOK_MOVECOST);
__asm {
@@ -725,7 +725,6 @@ static void __declspec(naked) HexMBlockingHook() {
static const DWORD _obj_blocking_at = 0x48B84E;
__asm {
HookBegin;
mov argCount, 4;
mov args[0], eax;
mov args[4], edx;
mov args[8], ebx;
@@ -743,6 +742,7 @@ return:
pushad;
}
argCount = 4;
RunHookScript(HOOK_HEXMOVEBLOCKING);
__asm {
@@ -757,7 +757,6 @@ return:
static void __declspec(naked) HexABlockingHook() {
__asm {
HookBegin;
mov argCount, 4;
mov args[0], eax;
mov args[4], edx;
mov args[8], ebx;
@@ -766,6 +765,7 @@ static void __declspec(naked) HexABlockingHook() {
pushad;
}
argCount = 4;
RunHookScript(HOOK_HEXAIBLOCKING);
__asm {
@@ -780,7 +780,6 @@ static void __declspec(naked) HexABlockingHook() {
static void __declspec(naked) HexShootBlockingHook() {
__asm {
HookBegin;
mov argCount, 4;
mov args[0], eax;
mov args[4], edx;
mov args[8], ebx;
@@ -789,6 +788,7 @@ static void __declspec(naked) HexShootBlockingHook() {
pushad;
}
argCount = 4;
RunHookScript(HOOK_HEXSHOOTBLOCKING);
__asm {
@@ -803,7 +803,6 @@ static void __declspec(naked) HexShootBlockingHook() {
static void __declspec(naked) HexSightBlockingHook() {
__asm {
HookBegin;
mov argCount, 4;
mov args[0], eax;
mov args[4], edx;
mov args[8], ebx;
@@ -812,6 +811,7 @@ static void __declspec(naked) HexSightBlockingHook() {
pushad;
}
argCount = 4;
RunHookScript(HOOK_HEXSIGHTBLOCKING);
__asm {
@@ -1352,6 +1352,8 @@ static long __fastcall InvenWieldHook_Script(TGameObj* critter, TGameObj* item,
}
static __declspec(noinline) bool InvenWieldHook_ScriptPart(long isWield, long isRemove = 0) {
argCount = 5;
args[3] = isWield; // unwield/wield event
args[4] = isRemove;
@@ -1371,7 +1373,6 @@ static void __declspec(naked) InvenWieldFuncHook() {
mov args[8], ebx; // slot
pushad;
}
argCount = 5;
// right hand slot?
if (args[2] != INVEN_TYPE_RIGHT_HAND && GetItemType((TGameObj*)args[1]) != item_type_armor) {
@@ -1398,7 +1399,6 @@ static void __declspec(naked) InvenUnwieldFuncHook() {
mov args[8], edx; // slot
pushad;
}
argCount = 5;
// set slot
if (args[2] == 0) { // left hand slot?
@@ -1429,7 +1429,6 @@ static void __declspec(naked) CorrectFidForRemovedItemHook() {
mov args[8], ebx; // item flag
pushadc;
}
argCount = 5;
// set slot
if (args[2] & ObjectFlag::Right_Hand) { // right hand slot
+15 -37
View File
@@ -592,29 +592,17 @@ static void mf_draw_image() {
frameno = opHandler.arg(1).rawValue();
}
FrmFile* frmPtr = nullptr;
if (LoadFrame(file, &frmPtr)) {
FrmFrameData* framePtr;
FrmFile* frmPtr = LoadArtFile(file, frameno, direction, framePtr);
if (frmPtr == nullptr) {
opHandler.printOpcodeError("draw_image() - cannot open the file: %s", file);
opHandler.setReturn(-1);
return;
}
FrmFrameData* framePtr = (FrmFrameData*)&frmPtr->width;
if (direction > 0 && direction < 6) {
BYTE* offsOriFrame = (BYTE*)framePtr;
offsOriFrame += frmPtr->oriFrameOffset[direction];
framePtr = (FrmFrameData*)offsOriFrame;
}
if (frameno > 0) {
int maxFrames = frmPtr->frames - 1;
if (frameno > maxFrames) frameno = maxFrames;
while (frameno-- > 0) {
BYTE* offsFrame = (BYTE*)framePtr;
offsFrame += framePtr->size + (sizeof(FrmFrameData) - 1);
framePtr = (FrmFrameData*)offsFrame;
}
}
// with x/y frame offsets
WindowDisplayBuf(x + frmPtr->xshift[direction], framePtr->width, y + frmPtr->yshift[direction], framePtr->height, framePtr->data, noTrans);
MemFree(frmPtr);
opHandler.setReturn(1);
}
@@ -651,27 +639,15 @@ static void mf_draw_image_scaled() {
frameno = opHandler.arg(1).rawValue();
}
FrmFile* frmPtr = nullptr;
if (LoadFrame(file, &frmPtr)) {
FrmFrameData* framePtr;
FrmFile* frmPtr = LoadArtFile(file, frameno, direction, framePtr);
if (frmPtr == nullptr) {
opHandler.printOpcodeError("draw_image_scaled() - cannot open the file: %s", file);
opHandler.setReturn(-1);
return;
}
FrmFrameData* framePtr = (FrmFrameData*)&frmPtr->width;
if (direction > 0 && direction < 6) {
BYTE* offsOriFrame = (BYTE*)framePtr;
offsOriFrame += frmPtr->oriFrameOffset[direction];
framePtr = (FrmFrameData*)offsOriFrame;
}
if (frameno > 0) {
int maxFrames = frmPtr->frames - 1;
if (frameno > maxFrames) frameno = maxFrames;
while (frameno-- > 0) {
BYTE* offsFrame = (BYTE*)framePtr;
offsFrame += framePtr->size + (sizeof(FrmFrameData) - 1);
framePtr = (FrmFrameData*)offsFrame;
}
}
long result = 1;
if (opHandler.numArgs() < 3) {
DisplayInWindow(framePtr->width, framePtr->width, framePtr->height, framePtr->data); // scaled to window size (w/o transparent)
} else {
@@ -691,16 +667,18 @@ static void mf_draw_image_scaled() {
s_height = s_width * framePtr->height / framePtr->width;
}
if (s_width <= 0 || s_height <= 0) {
opHandler.setReturn(0);
return;
result = 0;
goto exit;
}
long w_width = WindowWidth();
long xy_pos = (y * w_width) + x;
WindowTransCscale(framePtr->width, framePtr->height, s_width, s_height, xy_pos, w_width, framePtr->data); // custom scaling
}
exit:
MemFree(frmPtr);
opHandler.setReturn(1);
opHandler.setReturn(result);
}
static void mf_unwield_slot() {