From 4813b5656f2c7eb5c78d208960fa550f0dc7f5fa Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 2 Feb 2021 11:39:33 +0800 Subject: [PATCH] Code edits to ScriptExtender.cpp Updated FalloutStructs.h and ddraw.ini. --- artifacts/ddraw.ini | 2 +- sfall/FalloutStructs.h | 22 +++++++++++++------- sfall/HookScripts.cpp | 8 +++---- sfall/ScriptExtender.cpp | 45 ++++++++++++++++++++-------------------- sfall/ScriptExtender.h | 6 +++--- 5 files changed, 44 insertions(+), 39 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 714b21c8..82f784aa 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -808,7 +808,7 @@ HideObjIsNullMsg=0 ;Has pretty nasty side effects when saving/reloading, so don't use for regular gameplay DontDeleteProtos=0 -;Set to 1 to force sfall to search for global scripts every time the game loads rather than only the first time +;Set to 1 to force sfall to search for global/hook scripts every time the game loads rather than only the first time AlwaysFindScripts=0 ;Set to 1 to force critters to display combat float messages diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index b4229d9e..dc27ba99 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -247,20 +247,20 @@ struct TProgram { long field_8; long field_C; long *codePtr; - long field_14; - long field_18; + long field_14; // unused? + long field_18; // unused? long *dStackPtr; long *aStackPtr; long *dStackOffs; long *aStackOffs; long field_2C; long *stringRefPtr; - long field_34; // procTablePtr - long *procTablePtr; // field_38 - long regs[12]; - long field_6C; - long field_70; - long field_74; + long *procTablePtr; + long field_38; // 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 { @@ -278,6 +278,12 @@ struct TProgram { static_assert(sizeof(TProgram) == 140, "Incorrect TProgram definition."); +struct ProgramList { + TProgram* progPtr; + ProgramList* next; + ProgramList* prev; +}; + struct ItemButtonItem { TGameObj* item; union { diff --git a/sfall/HookScripts.cpp b/sfall/HookScripts.cpp index 42760fee..6f962633 100644 --- a/sfall/HookScripts.cpp +++ b/sfall/HookScripts.cpp @@ -1705,11 +1705,11 @@ void LoadHookScript(const char* name, int id) { dlog_f("Found hook script: %s\n", DL_HOOK, name); } -static void LoadHookScriptFile(const char* name, int id) { +static void InitHookScriptFile(const char* name, int id) { sScriptProgram prog; dlog("> ", DL_HOOK); dlog(name, DL_HOOK); - LoadScriptProgram(prog, name); + InitScriptProgram(prog, name); if (prog.ptr) { sHookScript hook; hook.prog = prog; @@ -1770,14 +1770,14 @@ void InitHookScripts() { dlogr("Running hook scripts...", DL_HOOK); for (std::vector::const_iterator it = hookScriptFilesList.begin(); it != hookScriptFilesList.end(); ++it) { - LoadHookScriptFile(it->name.c_str(), it->id); + InitHookScriptFile(it->name.c_str(), it->id); } initingHookScripts = 1; for (int i = 0; i < numHooks; i++) { if (!hooks[i].empty()) { hooksInfo[i].hasHsScript = true; - InitScriptProgram(hooks[i][0].prog); // zero hook is always hs_*.int script because Hook scripts are loaded BEFORE global scripts + RunScriptProgram(hooks[i][0].prog); // zero hook is always hs_*.int script because Hook scripts are loaded BEFORE global scripts } } initingHookScripts = 0; diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 59dab881..849942cd 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -1066,9 +1066,9 @@ static void __declspec(naked) ExecMapScriptsHack() { } static sExportedVar* __fastcall GetGlobalExportedVarPtr(const char* name) { + devlog_f("Trying to find exported var %s\n", DL_MAIN, name); std::string str(name); ExportedVarsMap::iterator it = globalExportedVars.find(str); - //dlog_f("\n Trying to find exported var %s... ", DL_MAIN, name); if (it != globalExportedVars.end()) { sExportedVar *ptr = &it->second; return ptr; @@ -1076,8 +1076,8 @@ static sExportedVar* __fastcall GetGlobalExportedVarPtr(const char* name) { return nullptr; } -static void __stdcall CreateGlobalExportedVar(DWORD scr, const char* name) { - //dlog_f("\nTrying to export variable %s (%d)\n", DL_MAIN, name, isGlobalScriptLoading); +static void __fastcall CreateGlobalExportedVar(TProgram* script, const char* name) { + devlog_f("Trying to export variable %s (%d)\n", DL_MAIN, name, isGlobalScriptLoading); std::string str(name); globalExportedVars[str] = sExportedVar(); // add new } @@ -1094,7 +1094,7 @@ static void __declspec(naked) Export_FetchOrStore_FindVar_Hook() { __asm { push ecx; push edx; - mov ecx, edx; // varName + mov ecx, edx; // varName call GetGlobalExportedVarPtr; pop edx; pop ecx; @@ -1108,19 +1108,18 @@ proceedNormal: } } -static void __declspec(naked) Export_Export_FindVar_Hook() { - static const DWORD Export_Export_FindVar_back = 0x4414AE; +static void __declspec(naked) exportExportVariable_hook() { + static const DWORD exportExportVariable_BackRet = 0x4414AE; __asm { cmp isGlobalScriptLoading, 0; jz proceedNormal; - push edx; // var name - push ebp; // script ptr - call CreateGlobalExportedVar; + mov ecx, ebp; // script ptr + call CreateGlobalExportedVar; // edx - var name xor eax, eax; - add esp, 4; // destroy return - jmp Export_Export_FindVar_back; // if sfall exported var, jump to the end of function + add esp, 4; // destroy return + jmp exportExportVariable_BackRet; // if sfall exported var, jump to the end of function proceedNormal: - jmp findVar_; // else - proceed normal + jmp findVar_; // else - proceed normal } } @@ -1268,7 +1267,7 @@ end: } // loads script from .int file into a sScriptProgram struct, filling script pointer and proc lookup table -void LoadScriptProgram(sScriptProgram &prog, const char* fileName) { +void InitScriptProgram(sScriptProgram &prog, const char* fileName) { TProgram* scriptPtr = fo_loadProgram(fileName); if (scriptPtr) { @@ -1278,17 +1277,17 @@ void LoadScriptProgram(sScriptProgram &prog, const char* fileName) { for (int i = 0; i < Scripts::count; ++i) { prog.procLookup[i] = fo_interpretFindProcedure(prog.ptr, procTable[i]); } - prog.initialized = 0; + prog.initialized = false; } else { prog.ptr = nullptr; } } -void InitScriptProgram(sScriptProgram &prog) { - if (prog.initialized == 0) { +void RunScriptProgram(sScriptProgram &prog) { + if (!prog.initialized) { fo_runProgram(prog.ptr); fo_interpret(prog.ptr, -1); - prog.initialized = 1; + prog.initialized = true; } } @@ -1328,7 +1327,7 @@ static void LoadGlobalScriptsList() { const std::string &scriptFile = *it; dlog("> ", DL_SCRIPT); dlog(scriptFile.c_str(), DL_SCRIPT); - LoadScriptProgram(prog, scriptFile.c_str()); + InitScriptProgram(prog, scriptFile.c_str()); if (prog.ptr) { sGlobalScript gscript = sGlobalScript(prog); gscript.startProc = prog.procLookup[Scripts::start]; // get 'start' procedure position @@ -1336,7 +1335,7 @@ static void LoadGlobalScriptsList() { AddProgramToMap(prog); dlogr(" Done", DL_SCRIPT); // initialize script (start proc will be executed for the first time) -- this needs to be after script is added to "globalScripts" array - InitScriptProgram(prog); + RunScriptProgram(prog); } else { dlogr(" Error!", DL_SCRIPT); } @@ -1368,7 +1367,7 @@ static void PrepareGlobalScriptsList() { std::string baseName(name); int lastDot = baseName.find_last_of('.'); if ((baseName.length() - lastDot) > 4) continue; // skip files with invalid extension (bug in db_get_file_list fuction) - dlog_f("Found global script: %s\n", DL_INIT, name); + dlog_f("Found global script: %s\n", DL_SCRIPT, name); baseName = baseName.substr(0, lastDot); // script name without extension if (!IsGameScript(baseName.c_str())) { @@ -1823,10 +1822,10 @@ void ScriptExtender_Init() { HookCall(0x4A3E08, script_chk_timed_events_hook); // this patch makes it possible to export variables from sfall global scripts - HookCall(0x4414C8, Export_Export_FindVar_Hook); + HookCall(0x4414C8, exportExportVariable_hook); const DWORD exportFindVarAddr[] = { - 0x441285, // store - 0x4413D9 // fetch + 0x441285, // exportStoreVariable_ + 0x4413D9 // exportFetchVariable_ }; HookCalls(Export_FetchOrStore_FindVar_Hook, exportFindVarAddr); diff --git a/sfall/ScriptExtender.h b/sfall/ScriptExtender.h index cfe47dfc..1141d9a9 100644 --- a/sfall/ScriptExtender.h +++ b/sfall/ScriptExtender.h @@ -32,7 +32,7 @@ enum SfallDataType : unsigned long { typedef struct { TProgram* ptr; int procLookup[Scripts::count]; - char initialized; + bool initialized; } sScriptProgram; #pragma pack(push, 8) @@ -70,10 +70,10 @@ int __stdcall ScriptHasLoaded(TProgram* script); // loads script from .int file into a sScriptProgram struct, filling script pointer and proc lookup table // prog - reference to program structure // fileName - the script file name without extension -void LoadScriptProgram(sScriptProgram &prog, const char* fileName); +void InitScriptProgram(sScriptProgram &prog, const char* fileName); // init program after load, needs to be called once -void InitScriptProgram(sScriptProgram &prog); +void RunScriptProgram(sScriptProgram &prog); // execute script by specific proc name void RunScriptProc(sScriptProgram* prog, const char* procName);