From b2c2a70822b0ef39a5ade4f4f08f535ea8dcb0de Mon Sep 17 00:00:00 2001 From: NovaRain Date: Thu, 6 May 2021 10:43:40 +0800 Subject: [PATCH] Set idle(Sleep) function for losing window focus Some code correction. --- artifacts/ddraw.ini | 4 ++-- sfall/BugFixes.cpp | 26 ++++++++++++++------------ sfall/FalloutFuncs_def.h | 2 +- sfall/FalloutStructs.h | 21 +++++++-------------- sfall/HookScripts.cpp | 2 +- sfall/MiscPatches.cpp | 4 ++++ sfall/ScriptExtender.cpp | 27 +++++++++++---------------- 7 files changed, 40 insertions(+), 46 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index c755bf96..bab8465c 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -415,7 +415,7 @@ CorpseDeleteTime=6 ;Set a number of milliseconds to idle each input loop ;Set to -1 to disable ;Set to 0 to idle only if other processes are waiting for processor time (WinXP/2000: if processes have equal priority) -;Set to 1 (or some higher number if needed) to prevent 100% CPU use. The maximum is 127 +;Set to 1 (or some higher number if needed) to prevent 100% CPU use. The maximum is 100 ProcessorIdle=-1 ;Set to 1 if using the hero appearance mod @@ -594,7 +594,7 @@ ObjCanSeeObj_ShootThru_Fix=0 ;Set to 1 to fix the broken obj_can_hear_obj script function ObjCanHearObjFix=0 -;Set to 1 to enable the mood argument of start_gdialog script function for talking heads +;Set to 1 to enable the 'mood' argument of start_gdialog script function for talking heads ;If the argument value is -1, the mood will be determined by the local variable 0 of the script (vanilla behavior) StartGDialogFix=0 diff --git a/sfall/BugFixes.cpp b/sfall/BugFixes.cpp index c815e477..0e5cb1ad 100644 --- a/sfall/BugFixes.cpp +++ b/sfall/BugFixes.cpp @@ -2318,10 +2318,12 @@ skip: static void __declspec(naked) exec_script_proc_hack() { __asm { - mov eax, [esi + 0x58]; + test edi, edi; // loading? + jnz end; + mov eax, [esi + 0x58]; // script.procedure_table.start test eax, eax; - ja end; - inc eax; // start proc + ja end; // != 0 + dec eax; // is bad - set to -1 for skipping execution end: retn; } @@ -2329,10 +2331,10 @@ end: static void __declspec(naked) exec_script_proc_hack1() { __asm { - mov esi, [edi + 0x58]; + mov esi, [edi + 0x58]; // script.procedure_table.start test esi, esi; - ja end; - inc esi; // start proc + ja end; // != 0 + inc esi; // 1 - default position end: retn; } @@ -3473,13 +3475,13 @@ void BugFixes_Init() // Fix for the incorrect item being checked for the presence of weapon perks HookCall(0x42954B, ai_best_weapon_hook); // Corrects the calculation of the weapon score to: (maxDmg + minDmg) / 4 - DWORD aiBestWeaponAddr[2] = {0x4294E2, 0x429675}; - SafeWriteBatch(0x01, aiBestWeaponAddr); // sub > add - aiBestWeaponAddr[0] = 0x4294E6; aiBestWeaponAddr[1] = 0x429679; - MakeCalls(ai_best_weapon_hack, aiBestWeaponAddr); + const DWORD aiBestWeaponAddr1[] = {0x4294E2, 0x429675}; + SafeWriteBatch(0x01, aiBestWeaponAddr1); // sub > add + const DWORD aiBestWeaponAddr2[] = {0x4294E6, 0x429679}; + MakeCalls(ai_best_weapon_hack, aiBestWeaponAddr2); // Corrects the weapon score multiplier for having perks to 2x (was 5x) - aiBestWeaponAddr[0] = 0x42955E; aiBestWeaponAddr[1] = 0x4296E7; - SafeWriteBatch(0x15, aiBestWeaponAddr); // lea eax, [edx*4] > lea eax, [edx] + const DWORD aiBestWeaponAddr3[] = {0x42955E, 0x4296E7}; + SafeWriteBatch(0x15, aiBestWeaponAddr3); // lea eax, [edx*4] > lea eax, [edx] dlogr(" Done", DL_FIX); } diff --git a/sfall/FalloutFuncs_def.h b/sfall/FalloutFuncs_def.h index 8d033cd6..7e8f0077 100644 --- a/sfall/FalloutFuncs_def.h +++ b/sfall/FalloutFuncs_def.h @@ -83,7 +83,7 @@ WRAP_WATCOM_FUNC1(long, critterIsOverloaded, TGameObj*, critter) WRAP_WATCOM_FUNC1(void, display_print, const char*, msg) // Displays message in main UI console window WRAP_WATCOM_FUNC0(void, display_stats) // Execute script proc by internal proc number (from script's proc table, basically a sequential number of a procedure as defined in code, starting from 1) -WRAP_WATCOM_FUNC2(void, executeProcedure, TProgram*, sptr, long, procNum) +WRAP_WATCOM_FUNC2(void, executeProcedure, TProgram*, sptr, long, procPosition) WRAP_WATCOM_FUNC1(long, folder_print_line, const char*, text) WRAP_WATCOM_FUNC1(const char*, findCurrentProc, TProgram*, program) // Returns the name of current procedure by program pointer WRAP_WATCOM_FUNC1(long, FMtext_width, const char*, text) diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index d3422ed4..8e9661a9 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -263,7 +263,7 @@ struct TProgram { long *codeStackPtr; long field_8; long field_C; - long *codePtr; + long codePosition; // position in the code stack when reading script opcodes long field_14; // unused? long field_18; // unused? long *dStackPtr; @@ -273,24 +273,17 @@ struct TProgram { long field_2C; long *stringRefPtr; long *procTablePtr; - long field_38; // same as codeStackPtr + long *codeStack; // same as codeStackPtr long savedEnv[12]; // saved register values long field_6C; // unused? long field_70; // unused? long field_74; // unused? - long field_78; - long field_7C; - union { - long flags; - struct { - char flags1; - char flags2; - char flags3; - char flags4; - }; - }; + long timerTick; // unused? + long func_7C; // always null? + short flags; + short fetchOpcode; long currentScriptWin; // current window for executing script - long field_88; + long shouldRemove; }; static_assert(sizeof(TProgram) == 140, "Incorrect TProgram definition."); diff --git a/sfall/HookScripts.cpp b/sfall/HookScripts.cpp index 07547c8e..6aa9a90a 100644 --- a/sfall/HookScripts.cpp +++ b/sfall/HookScripts.cpp @@ -35,7 +35,7 @@ static const int numHooks = HOOK_COUNT; // Struct for registered hook script struct sHookScript { sScriptProgram prog; - int callback; // proc number in script's proc table + int callback; // procedure position in script's proc table bool isGlobalScript; // false for hs_* scripts, true for gl* scripts }; diff --git a/sfall/MiscPatches.cpp b/sfall/MiscPatches.cpp index 55f4b667..0ae254fe 100644 --- a/sfall/MiscPatches.cpp +++ b/sfall/MiscPatches.cpp @@ -758,6 +758,10 @@ void MiscPatches_Init() { dlogr(" Done", DL_INIT); } + // Set idle function + *ptr_idle_func = reinterpret_cast(Sleep); + SafeWrite16(0x4C9F12, 0x7D6A); // push 125 (ms) + BlockCall(0x4425E6); // Patch out ereg call SafeWrite8(0x4810AB, CODETYPE_JumpShort); // Disable selfrun diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 63804c17..cd0f1e17 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -1177,27 +1177,27 @@ static void ClearGlobalScripts() { void RunScriptProc(sScriptProgram* prog, const char* procName) { TProgram* sptr = prog->ptr; - int procNum = fo_interpretFindProcedure(sptr, procName); - if (procNum != -1) { - fo_executeProcedure(sptr, procNum); + int procPosition = fo_interpretFindProcedure(sptr, procName); + if (procPosition != -1) { + fo_executeProcedure(sptr, procPosition); } } void RunScriptProc(sScriptProgram* prog, long procId) { if (procId > 0 && procId < Scripts::count) { - int procNum = prog->procLookup[procId]; - if (procNum != -1) { - fo_executeProcedure(prog->ptr, procNum); + int procPosition = prog->procLookup[procId]; + if (procPosition != -1) { + fo_executeProcedure(prog->ptr, procPosition); } } } int RunScriptStartProc(sScriptProgram* prog) { - int procNum = prog->procLookup[Scripts::start]; - if (procNum != -1) { - fo_executeProcedure(prog->ptr, procNum); + int procPosition = prog->procLookup[Scripts::start]; + if (procPosition != -1) { + fo_executeProcedure(prog->ptr, procPosition); } - return procNum; + return procPosition; } static void RunScript(sGlobalScript* script) { @@ -1532,12 +1532,7 @@ void ScriptExtender_Init() { } idle = GetConfigInt("Misc", "ProcessorIdle", -1); - if (idle > -1) { - if (idle > 127) idle = 127; - *ptr_idle_func = reinterpret_cast(Sleep); - SafeWrite8(0x4C9F12, 0x6A); // push idle - SafeWrite8(0x4C9F13, idle); - } + if (idle > -1 && idle > 100) idle = 100; arraysBehavior = GetConfigInt("Misc", "arraysBehavior", 1); if (arraysBehavior > 0) {