diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 1a54ee05..766110a2 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -98,6 +98,7 @@ const DWORD critter_name_ = 0x42D0A8; const DWORD critter_pc_set_name_ = 0x42D138; const DWORD critterClearObjDrugs_ = 0x42DA54; const DWORD critterIsOverloaded_ = 0x42E66C; +const DWORD db_access_ = 0x4390B4; const DWORD db_dir_entry_ = 0x4C5D68; const DWORD db_fclose_ = 0x4C5EB4; const DWORD db_fgetc_ = 0x4C5F24; @@ -110,10 +111,12 @@ const DWORD db_freadInt_ = 0x4C614C; const DWORD db_freadIntCount_ = 0x4C63BC; const DWORD db_freadShort_ = 0x4C60F4; const DWORD db_freadShortCount_ = 0x4C6330; +const DWORD db_free_file_list_ = 0x4C6868; const DWORD db_fseek_ = 0x4C60C0; const DWORD db_fwriteByte_ = 0x4C61AC; const DWORD db_fwriteByteCount_ = 0x4C6464; const DWORD db_fwriteInt_ = 0x4C6214; +const DWORD db_get_file_list_ = 0x4C6628; const DWORD db_read_to_buf_ = 0x4C5DD4; const DWORD dbase_close_ = 0x4E5270; const DWORD dbase_open_ = 0x4E4F58; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 20dd139c..3163e649 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -116,6 +116,7 @@ #define _map_global_vars 0x51956C #define _master_db_handle 0x58E948 #define _max 0x56FB50 +#define _maxScriptNum 0x51C7CC #define _Meet_Frank_Horrigan 0x672E04 #define _mouse_hotx 0x6AC7D0 #define _mouse_hoty 0x6AC7CC @@ -164,6 +165,7 @@ #define _RedColor 0x6AB4D0 #define _retvals 0x43EA7C #define _scr_size 0x6AC9F0 +#define _scriptListInfo 0x51C7C8 #define _skill_data 0x51D118 #define _slot_cursor 0x5193B8 #define _sneak_working 0x56D77C // DWORD var @@ -261,6 +263,7 @@ extern const DWORD critter_name_; extern const DWORD critter_pc_set_name_; extern const DWORD critterClearObjDrugs_; extern const DWORD critterIsOverloaded_; +extern const DWORD db_access_; extern const DWORD db_dir_entry_; extern const DWORD db_fclose_; extern const DWORD db_fgetc_; @@ -273,10 +276,12 @@ extern const DWORD db_freadInt_; extern const DWORD db_freadIntCount_; extern const DWORD db_freadShort_; extern const DWORD db_freadShortCount_; +extern const DWORD db_free_file_list_; extern const DWORD db_fseek_; extern const DWORD db_fwriteByte_; extern const DWORD db_fwriteByteCount_; extern const DWORD db_fwriteInt_; +extern const DWORD db_get_file_list_; extern const DWORD db_read_to_buf_; extern const DWORD dbase_close_; extern const DWORD dbase_open_; diff --git a/sfall/HookScripts.cpp b/sfall/HookScripts.cpp index bb680d46..8c482b88 100644 --- a/sfall/HookScripts.cpp +++ b/sfall/HookScripts.cpp @@ -1099,20 +1099,21 @@ void _stdcall RegisterHook( DWORD script, DWORD id, DWORD procNum ) static void LoadHookScript(const char* name, int id) { if (id >= numHooks) return; - WIN32_FIND_DATA file; - HANDLE h; - char buf[MAX_PATH]; - sprintf(buf, "%s\\scripts\\hs_%s.int", *(char**)_patches, name); - h = FindFirstFileA(buf, &file); - if(h != INVALID_HANDLE_VALUE) { + char filename[MAX_PATH]; + sprintf(filename, "scripts\\%s.int", name); + bool result; + __asm { + lea eax, filename + call db_access_ + mov result, al + } + + if (result && !isGameScript(name)) { sScriptProgram prog; dlog("Loading hook script: ", DL_HOOK); - dlogr(buf, DL_HOOK); - char* fName = file.cFileName; - fName[strlen(fName) - 4] = 0; - LoadScriptProgram(prog, fName); - FindClose(h); + dlog(filename, DL_HOOK); + LoadScriptProgram(prog, name); if (prog.ptr) { sHookScript hook; hook.prog = prog; @@ -1120,13 +1121,24 @@ static void LoadHookScript(const char* name, int id) { hook.isGlobalScript = false; hooks[id].push_back(hook); AddProgramToMap(prog); - } + dlogr(" Done", DL_HOOK); + } else dlogr(" Error!", DL_HOOK); } } + static void HookScriptInit2() { dlogr("Initing hook scripts", DL_HOOK|DL_INIT); - LoadHookScript("tohit", HOOK_TOHIT); + char* mask = "scripts\\hs_*.int"; + DWORD *filenames; + __asm { + xor ebx, ebx + mov eax, mask + lea edx, filenames + call db_get_file_list_ + } + + LoadHookScript("hs_tohit", HOOK_TOHIT); HookCall(0x421686, &ToHitHook); HookCall(0x4231D9, &ToHitHook); HookCall(0x42331F, &ToHitHook); @@ -1136,10 +1148,10 @@ static void HookScriptInit2() { HookCall(0x42439C, &ToHitHook); HookCall(0x42679A, &ToHitHook); - LoadHookScript("afterhitroll", HOOK_AFTERHITROLL); + LoadHookScript("hs_afterhitroll", HOOK_AFTERHITROLL); MakeCall(0x423893, &AfterHitRollHook, true); - LoadHookScript("calcapcost", HOOK_CALCAPCOST); + LoadHookScript("hs_calcapcost", HOOK_CALCAPCOST); HookCall(0x42307A, &CalcApCostHook); HookCall(0x42669F, &CalcApCostHook); HookCall(0x42687B, &CalcApCostHook); @@ -1152,14 +1164,14 @@ static void HookScriptInit2() { HookCall(0x47807B, &CalcApCostHook); MakeCall(0x478083, &CalcApCostHook2, false); - LoadHookScript("deathanim1", HOOK_DEATHANIM1); - LoadHookScript("deathanim2", HOOK_DEATHANIM2); + LoadHookScript("hs_deathanim1", HOOK_DEATHANIM1); + LoadHookScript("hs_deathanim2", HOOK_DEATHANIM2); HookCall(0x4109DE, &CalcDeathAnimHook); HookCall(0x410981, &CalcDeathAnimHook2); HookCall(0x4109A1, &CalcDeathAnimHook2); HookCall(0x4109BF, &CalcDeathAnimHook2); - LoadHookScript("combatdamage", HOOK_COMBATDAMAGE); + LoadHookScript("hs_combatdamage", HOOK_COMBATDAMAGE); HookCall(0x42326C, &CombatDamageHook); // check_ranged_miss() HookCall(0x4233E3, &CombatDamageHook); // shoot_along_path() - for extra burst targets HookCall(0x423AB7, &CombatDamageHook); // compute_attack() @@ -1169,7 +1181,7 @@ static void HookScriptInit2() { HookCall(0x424220, &CombatDamageHook); // attack_crit_failure() HookCall(0x4242FB, &CombatDamageHook); // attack_crit_failure() - LoadHookScript("ondeath", HOOK_ONDEATH); + LoadHookScript("hs_ondeath", HOOK_ONDEATH); HookCall(0x4130CC, &OnDeathHook); HookCall(0x4130EF, &OnDeathHook); HookCall(0x413603, &OnDeathHook); @@ -1182,10 +1194,10 @@ static void HookScriptInit2() { HookCall(0x4C14F9, &OnDeathHook); HookCall(0x425161, &OnDeathHook2); - LoadHookScript("findtarget", HOOK_FINDTARGET); + LoadHookScript("hs_findtarget", HOOK_FINDTARGET); HookCall(0x429143, &FindTargetHook); - LoadHookScript("useobjon", HOOK_USEOBJON); + LoadHookScript("hs_useobjon", HOOK_USEOBJON); HookCall(0x49C606, &UseObjOnHook); HookCall(0x473619, &UseObjOnHook); // the following hooks allows to catch drug use of AI and from action cursor @@ -1194,22 +1206,22 @@ static void HookScriptInit2() { HookCall(0x4287F8, &UseObjOnHook_item_d_take_drug); // ai_check_drugs HookCall(0x473573, &UseObjOnHook_item_d_take_drug); // inven_action_cursor - LoadHookScript("removeinvenobj", HOOK_REMOVEINVENOBJ); + LoadHookScript("hs_removeinvenobj", HOOK_REMOVEINVENOBJ); MakeCall(0x477490, &RemoveObjHook, true); - LoadHookScript("barterprice", HOOK_BARTERPRICE); + LoadHookScript("hs_barterprice", HOOK_BARTERPRICE); HookCall(0x474D4C, &BarterPriceHook); HookCall(0x475735, &BarterPriceHook); HookCall(0x475762, &BarterPriceHook); - LoadHookScript("movecost", HOOK_MOVECOST); + LoadHookScript("hs_movecost", HOOK_MOVECOST); HookCall(0x417665, &MoveCostHook); HookCall(0x44B88A, &MoveCostHook); - LoadHookScript("hexmoveblocking", HOOK_HEXMOVEBLOCKING); - LoadHookScript("hexaiblocking", HOOK_HEXAIBLOCKING); - LoadHookScript("hexshootblocking", HOOK_HEXSHOOTBLOCKING); - LoadHookScript("hexsightblocking", HOOK_HEXSIGHTBLOCKING); + LoadHookScript("hs_hexmoveblocking", HOOK_HEXMOVEBLOCKING); + LoadHookScript("hs_hexaiblocking", HOOK_HEXAIBLOCKING); + LoadHookScript("hs_hexshootblocking", HOOK_HEXSHOOTBLOCKING); + LoadHookScript("hs_hexsightblocking", HOOK_HEXSIGHTBLOCKING); SafeWrite32(0x413979, (DWORD)&HexSightBlockingHook); SafeWrite32(0x4C1A88, (DWORD)&HexShootBlockingHook); SafeWrite32(0x423178, (DWORD)&HexShootBlockingHook); @@ -1220,29 +1232,29 @@ static void HookScriptInit2() { SafeWrite32(0x42A0A4, (DWORD)&HexABlockingHook); MakeCall(0x48B848, &HexMBlockingHook, true); - LoadHookScript("itemdamage", HOOK_ITEMDAMAGE); + LoadHookScript("hs_itemdamage", HOOK_ITEMDAMAGE); HookCall(0x478560, &ItemDamageHook); - LoadHookScript("ammocost", HOOK_AMMOCOST); + LoadHookScript("hs_ammocost", HOOK_AMMOCOST); HookCall(0x423A7C, &AmmoCostHook); - LoadHookScript("useobj", HOOK_USEOBJ); + LoadHookScript("hs_useobj", HOOK_USEOBJ); HookCall(0x42AEBF, &UseObjHook); HookCall(0x473607, &UseObjHook); HookCall(0x49C12E, &UseObjHook); - LoadHookScript("keypress", HOOK_KEYPRESS); - LoadHookScript("mouseclick", HOOK_MOUSECLICK); + LoadHookScript("hs_keypress", HOOK_KEYPRESS); + LoadHookScript("hs_mouseclick", HOOK_MOUSECLICK); - LoadHookScript("useskill", HOOK_USESKILL); + LoadHookScript("hs_useskill", HOOK_USESKILL); HookCall(0x49C48F, &UseSkillHook); HookCall(0x49D12E, &UseSkillHook); - LoadHookScript("steal", HOOK_STEAL); + LoadHookScript("hs_steal", HOOK_STEAL); HookCall(0x4749A2, &StealCheckHook); HookCall(0x474A69, &StealCheckHook); - LoadHookScript("withinperception", HOOK_WITHINPERCEPTION); + LoadHookScript("hs_withinperception", HOOK_WITHINPERCEPTION); HookCall(0x429157, &PerceptionRangeHook); HookCall(0x42B4ED, &PerceptionRangeHook); HookCall(0x42BC87, &PerceptionRangeHook); @@ -1251,7 +1263,7 @@ static void HookScriptInit2() { MakeCall(0x456BA2, &PerceptionRangeBonusHack, true); HookCall(0x458403, &PerceptionRangeHook); - LoadHookScript("inventorymove", HOOK_INVENTORYMOVE); + LoadHookScript("hs_inventorymove", HOOK_INVENTORYMOVE); HookCall(0x4712E3, &SwitchHandHook); // left slot HookCall(0x47136D, &SwitchHandHook); // right slot MakeCall(0x4713A3, &UseArmorHack, true); @@ -1262,7 +1274,7 @@ static void HookScriptInit2() { //HookCall(0x471351, &DropAmmoIntoWeaponHook); MakeCall(0x476588, &DropAmmoIntoWeaponHack, true); - LoadHookScript("invenwield", HOOK_INVENWIELD); + LoadHookScript("hs_invenwield", HOOK_INVENWIELD); HookCall(0x47275E, &invenWieldFunc_Hook); HookCall(0x495FDF, &invenWieldFunc_Hook); HookCall(0x45967D, &invenUnwieldFunc_Hook); @@ -1271,8 +1283,13 @@ static void HookScriptInit2() { HookCall(0x45680C, &correctFidForRemovedItem_Hook); HookCall(0x45C4EA, &correctFidForRemovedItem_Hook); - dlogr("Completed hook script init", DL_HOOK|DL_INIT); + __asm { + xor edx, edx + lea eax, filenames + call db_free_file_list_ + } + dlogr("Completed hook script init", DL_HOOK|DL_INIT); } void HookScriptClear() { diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index f4c4c11a..5523e712 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -96,7 +96,7 @@ static float _stdcall GetOpArgFloat(int num) { } static const char* _stdcall GetOpArgStr(int num) { - return (opArgTypes[num] == DATATYPE_STR) + return (opArgTypes[num] == DATATYPE_STR) ? (const char*)opArgs[num] : ""; } @@ -145,7 +145,7 @@ struct sGlobalScript { struct sExportedVar { DWORD type; // in scripting engine terms, eg. VAR_TYPE_* - DWORD val; + DWORD val; sExportedVar() : val(0), type(VAR_TYPE_INT) {} }; @@ -634,7 +634,7 @@ DWORD _stdcall FindSidHook2(DWORD script) { return -2; // override struct } // this will allow to use functions like roll_vs_skill, etc without calling set_self (they don't really need self object) - if (sfallProgsMap.find(script) != sfallProgsMap.end()) { + if (sfallProgsMap.find(script) != sfallProgsMap.end()) { OverrideScriptStruct.target_obj = OverrideScriptStruct.self_obj = 0; return -2; // override struct } @@ -749,7 +749,7 @@ static DWORD __stdcall CreateGlobalExportedVar(DWORD scr, const char* name) { globalExportedVars[str] = sExportedVar(); // add new return 1; } -/* +/* when fetching/storing into exported variables, first search in our own hash table instead, then (if not found), resume normal search reason for this: game frees all scripts and exported variables from memory when you exit map @@ -905,7 +905,7 @@ end: } void ScriptExtenderSetup() { - bool AllowUnsafeScripting = IsDebug + bool AllowUnsafeScripting = IsDebug && GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ".\\ddraw.ini") != 0; toggleHighlightsKey = GetPrivateProfileIntA("Input", "ToggleItemHighlightsKey", 0, ini); @@ -1299,6 +1299,7 @@ void InitScriptProgram(sScriptProgram &prog) { void AddProgramToMap(sScriptProgram &prog) { sfallProgsMap[prog.ptr] = prog; } + sScriptProgram* GetGlobalScriptProgram(DWORD scriptPtr) { for (std::vector::iterator it = globalScripts.begin(); it != globalScripts.end(); it++) { if (it->prog.ptr == scriptPtr) return &it->prog; @@ -1306,25 +1307,38 @@ sScriptProgram* GetGlobalScriptProgram(DWORD scriptPtr) { return NULL; } +bool _stdcall isGameScript(const char* filename) { + for (DWORD i = 0; i < *(DWORD*)_maxScriptNum; i++) { + if (strcmp(filename, (char*)(*(DWORD*)_scriptListInfo + i*20)) == 0) return true; + } + return false; +} + // this runs after the game was loaded/started void LoadGlobalScripts() { isGameLoading = false; HookScriptInit(); dlogr("Loading global scripts", DL_SCRIPT); - WIN32_FIND_DATA file; - char buf[MAX_PATH]; - sprintf(buf, "%s\\scripts\\gl*.int", *(char**)_patches); - HANDLE h = FindFirstFileA(buf, &file); - if (h != INVALID_HANDLE_VALUE) { - char* fName = file.cFileName; - // TODO: refactor script programs - sScriptProgram prog; - DWORD found = 1; - while (found) { - fName[strlen(fName) - 4] = 0; - dlogr(fName, DL_SCRIPT); + + char* name = "scripts\\gl*.int"; + DWORD count, *filenames; + __asm { + xor ebx, ebx + mov eax, name + lea edx, filenames + call db_get_file_list_ + mov count, eax + } + + // TODO: refactor script programs + sScriptProgram prog; + for (DWORD i = 0; i < count; i++) { + name = _strlwr((char*)filenames[i]); + name[strlen(name) - 4] = 0; + if (!isGameScript(name)) { + dlog(name, DL_SCRIPT); isGlobalScriptLoading = 1; - LoadScriptProgram(prog, fName); + LoadScriptProgram(prog, name); if (prog.ptr) { DWORD idx; sGlobalScript gscript = sGlobalScript(prog); @@ -1333,13 +1347,17 @@ void LoadGlobalScripts() { AddProgramToMap(prog); // initialize script (start proc will be executed for the first time) -- this needs to be after script is added to "globalScripts" array InitScriptProgram(prog); - } + dlogr(" Done", DL_SCRIPT); + } else dlogr(" Error!", DL_SCRIPT); isGlobalScriptLoading = 0; - found = FindNextFileA(h, &file); } - FindClose(h); } - dlogr("Finished loading global scripts", DL_SCRIPT); + __asm { + xor edx, edx + lea eax, filenames + call db_free_file_list_ + } + dlogr("Finished loading global scripts", DL_SCRIPT); //ButtonsReload(); } @@ -1421,7 +1439,7 @@ static void RunScript(sGlobalScript* script) { */ static void ResetStateAfterFrame() { if (tempArrays.size()) { - for (std::set::iterator it = tempArrays.begin(); it != tempArrays.end(); ++it) + for (std::set::iterator it = tempArrays.begin(); it != tempArrays.end(); ++it) FreeArray(*it); tempArrays.clear(); } @@ -1551,7 +1569,7 @@ void SaveGlobals(HANDLE h) { void ClearGlobals() { globalVars.clear(); - for (array_itr it = arrays.begin(); it != arrays.end(); ++it) + for (array_itr it = arrays.begin(); it != arrays.end(); ++it) it->second.clear(); arrays.clear(); savedArrays.clear(); diff --git a/sfall/ScriptExtender.h b/sfall/ScriptExtender.h index a9229524..f8cc7428 100644 --- a/sfall/ScriptExtender.h +++ b/sfall/ScriptExtender.h @@ -39,6 +39,7 @@ typedef struct } sScriptProgram; void ScriptExtenderSetup(); +bool _stdcall isGameScript(const char* filename); void LoadGlobalScripts(); void ClearGlobalScripts(); diff --git a/sfall/ddraw2.cpp b/sfall/ddraw2.cpp index 7506fb69..62f8b267 100644 --- a/sfall/ddraw2.cpp +++ b/sfall/ddraw2.cpp @@ -185,7 +185,6 @@ int _stdcall LoadShader(const char* path) { shader.Effect->SetFloatArray("rcpres", rcpres, 2); for(int i=1;i<128;i++) { - char buf[MAX_PATH]; const char* name; IDirect3DTexture9* tex;