From 712eafc2413d0c85e3314f41ac1b55d3cca293c3 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Mon, 3 Oct 2016 14:46:51 +0800 Subject: [PATCH] Now sfall loads global/hook scripts, shaders, 32-bit talking heads images, and avi movies according to the paths variables in the cfg file, instead of from the fixed "Data\". Removed GainStatPerkFix from ddraw.ini. Removed BodyHit_Uncalled from ddraw.ini. Now "uncalled" shares the same modifier with "torso", because separating them would result in some illogical setups. --- artifacts/ddraw.ini | 4 --- sfall/HookScripts.cpp | 12 ++++---- sfall/LoadGameHook.cpp | 63 +++++++++------------------------------- sfall/Perks.cpp | 22 ++++++++++---- sfall/ScriptExtender.cpp | 6 ++-- sfall/ddraw2.cpp | 6 ++-- sfall/heads.cpp | 22 +++++++------- sfall/movies.cpp | 12 +++++--- 8 files changed, 61 insertions(+), 86 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index e063b6b9..4fdbe2cc 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -291,9 +291,6 @@ SingleCore=1 ;Set to 1 to override the art_chache_size setting in fallout2.cfg OverrideArtCacheSize=0 -;Set to 1 to fix issues with the GainXXX perks not giving all the bonuses that they should -GainStatPerkFix=1 - ;Prevents you from saving in combat except at the start of your turn to avoid a few bugs ;Note that even with this option enabled, it is still not advisable to save in combat at all. ;Set to 2 to block all saving in combat @@ -320,7 +317,6 @@ AdditionalWeaponAnims=1 ;BodyHit_Left_Leg=-20 ;BodyHit_Eyes=-60 ;BodyHit_Groin=-30 -;BodyHit_Uncalled=0 ;Set to 1 to use a CriticalOverrides.ini file to override the default critical table ;Set to 2 to use the default critical with bug fixes (doesn't require an ini) diff --git a/sfall/HookScripts.cpp b/sfall/HookScripts.cpp index 8bd7134c..bb680d46 100644 --- a/sfall/HookScripts.cpp +++ b/sfall/HookScripts.cpp @@ -1096,17 +1096,19 @@ void _stdcall RegisterHook( DWORD script, DWORD id, DWORD procNum ) hooks[id].push_back(hook); } } -#define LoadHookScript(a,b) _LoadHookScript("data\\scripts\\hs_" a ".int", b) -static void _LoadHookScript(const char* path, int id) { - if(id>=numHooks) return; + +static void LoadHookScript(const char* name, int id) { + if (id >= numHooks) return; WIN32_FIND_DATA file; HANDLE h; - h = FindFirstFileA(path, &file); + char buf[MAX_PATH]; + sprintf(buf, "%s\\scripts\\hs_%s.int", *(char**)_patches, name); + h = FindFirstFileA(buf, &file); if(h != INVALID_HANDLE_VALUE) { sScriptProgram prog; dlog("Loading hook script: ", DL_HOOK); - dlogr(path, DL_HOOK); + dlogr(buf, DL_HOOK); char* fName = file.cFileName; fName[strlen(fName) - 4] = 0; LoadScriptProgram(prog, fName); diff --git a/sfall/LoadGameHook.cpp b/sfall/LoadGameHook.cpp index 5cb11ff6..cc43c27e 100644 --- a/sfall/LoadGameHook.cpp +++ b/sfall/LoadGameHook.cpp @@ -44,32 +44,12 @@ #define MAX_GLOBAL_SIZE (MaxGlobalVars*12 + 4) static DWORD InLoop=0; -DWORD GainStatFix=0; static DWORD SaveInCombatFix; DWORD InWorldMap() { return (InLoop&WORLDMAP)?1:0; } DWORD InCombat() { return (InLoop&COMBAT)?1:0; } DWORD GetCurrentLoops() { return InLoop; } -static void ModifyGainXXXPerks() { - SafeWrite8(0x004AF11F, 0xeb); //Strength - SafeWrite8(0x004AF181, 0xeb); //Perception - SafeWrite8(0x004AF19D, 0xeb); //Endurance - SafeWrite8(0x004AF1BD, 0xeb); //Charisma - SafeWrite8(0x004AF214, 0xeb); //Intelligance - SafeWrite8(0x004AF230, 0xeb); //Agility - SafeWrite8(0x004AF24B, 0xeb); //Luck -} -static void RestoreGainXXXPerks() { - SafeWrite8(0x004AF11F, 0x74); //Strength - SafeWrite8(0x004AF181, 0x74); //Perception - SafeWrite8(0x004AF19D, 0x74); //Endurance - SafeWrite8(0x004AF1BD, 0x74); //Charisma - SafeWrite8(0x004AF214, 0x74); //Intelligance - SafeWrite8(0x004AF230, 0x74); //Agility - SafeWrite8(0x004AF24B, 0x74); //Luck -} - static void _stdcall ResetState(DWORD onLoad) { if(!onLoad) FileSystemReset(); ClearGlobalScripts(); @@ -80,8 +60,6 @@ static void _stdcall ResetState(DWORD onLoad) { Knockback_OnGameLoad(); Skills_OnGameLoad(); InLoop=0; - GainStatFix=0; - RestoreGainXXXPerks(); PerksReset(); InventoryReset(); RegAnimCombatCheck(1); @@ -101,13 +79,13 @@ static void _stdcall SaveGame2() { dlog_f("Saving game: %s\r\n", DL_MAIN, buf); - DWORD unused; - DWORD unused2=0; - HANDLE h=CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); - if(h!=INVALID_HANDLE_VALUE) { + DWORD size, unused = 0; + HANDLE h = CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); + if (h != INVALID_HANDLE_VALUE) { SaveGlobals(h); - WriteFile(h, &unused2, 4, &unused, 0); - WriteFile(h, &GainStatFix, 4, &unused, 0); + WriteFile(h, &unused, 4, &size, 0); + unused++; + WriteFile(h, &unused, 4, &size, 0); PerksSave(h); SaveArrays(h); CloseHandle(h); @@ -117,8 +95,8 @@ static void _stdcall SaveGame2() { PlaySfx("IISXXXX1"); } GetSavePath(buf, "fs"); - h=CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); - if(h!=INVALID_HANDLE_VALUE) { + h = CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); + if (h != INVALID_HANDLE_VALUE) { FileSystemSave(h); } CloseHandle(h); @@ -191,27 +169,20 @@ static void _stdcall LoadGame2_After() { dlog_f("Loading save game: %s\r\n", DL_MAIN, buf); ClearGlobals(); - HANDLE h=CreateFileA(buf, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if(h!=INVALID_HANDLE_VALUE) { - DWORD size=0; - DWORD unused; + HANDLE h = CreateFileA(buf, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if (h != INVALID_HANDLE_VALUE) { + DWORD size, unused[2]; LoadGlobals(h); - ReadFile(h, (&unused), 4, &size, 0); - ReadFile(h, &GainStatFix, 4, &size, 0); - if(!size) GainStatFix = 0; - else { + ReadFile(h, &unused, 8, &size, 0); + if (size == 8) { PerksLoad(h); LoadArrays(h); } CloseHandle(h); } else { - GainStatFix = 0; dlogr("Cannot read sfallgv.sav - assuming non-sfall save.", DL_MAIN); } - if(GainStatFix) ModifyGainXXXPerks(); - else RestoreGainXXXPerks(); - LoadGlobalScripts(); CritLoad(); LoadHeroAppearance(); @@ -260,14 +231,6 @@ static void NewGame2() { SetNewCharAppearanceGlobals(); - if(GetPrivateProfileInt("Misc", "GainStatPerkFix", 1, ini)) { - ModifyGainXXXPerks(); - GainStatFix=1; - } else { - RestoreGainXXXPerks(); - GainStatFix=0; - } - /*if (GetPrivateProfileInt("Misc", "PipBoyAvailableAtGameStart", 0, ini)) { SafeWrite8(0x596C7B, 1); } diff --git a/sfall/Perks.cpp b/sfall/Perks.cpp index 36d01828..fc838962 100644 --- a/sfall/Perks.cpp +++ b/sfall/Perks.cpp @@ -78,7 +78,6 @@ vector fakeTraits; vector fakePerks; vector fakeSelectablePerks; -extern DWORD GainStatFix; static DWORD RemoveTraitID; static DWORD RemovePerkID; static DWORD RemoveSelectableID; @@ -91,6 +90,16 @@ static char PerkBoxTitle[64]; static DWORD PerkFreqOverride; +static const DWORD GainStatPerks[7][2] = { + {0x4AF122, 0xC9}, // Strength // mov ecx, ecx + {0x4AF184, 0xC9}, // Perception + {0x4AF19F, 0x90}, // Endurance // nop + {0x4AF1C0, 0xC9}, // Charisma + {0x4AF217, 0xC9}, // Intelligance + {0x4AF232, 0x90}, // Agility + {0x4AF24D, 0x90}, // Luck +}; + void _stdcall SetPerkFreq(int i) { PerkFreqOverride=i; } @@ -567,10 +576,7 @@ static void __declspec(naked) AddPerkHook() { end: push edx; call perk_add_; - mov edx, GainStatFix; - test edx, edx; pop edx; - jz end2; test eax, eax; jnz end2; cmp edx, 84; @@ -982,14 +988,18 @@ void _stdcall SetPerkDesc(int id, char* value) { strcpy_s(&Desc[id*1024], 1024, value); Perks[id].Desc=&Desc[1024*id]; } + void PerksInit() { + for (int i = STAT_st; i <= STAT_lu; i++) SafeWrite8(GainStatPerks[i][0], (BYTE)GainStatPerks[i][1]); + HookCall(0x442729, &PerkInitWrapper); - if(GetPrivateProfileString("Misc", "PerksFile", "", &perksFile[2], 257, ini)) { + if (GetPrivateProfileString("Misc", "PerksFile", "", &perksFile[2], 257, ini)) { perksFile[0]='.'; perksFile[1]='\\'; HookCall(0x44272E, &TraitInitWrapper); - } else perksFile[0]=0; + } else perksFile[0] = 0; } + void PerksReset() { fakeTraits.clear(); fakePerks.clear(); diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index c13e5cd4..b44bdda0 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -1325,7 +1325,9 @@ void LoadGlobalScripts() { HookScriptInit(); dlogr("Loading global scripts", DL_SCRIPT); WIN32_FIND_DATA file; - HANDLE h=FindFirstFileA("data\\scripts\\gl*.int", &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 @@ -1393,7 +1395,7 @@ void ClearGlobalScripts() { *((DWORD*)0x510968) = GetPrivateProfileIntA("Misc", "BodyHit_Left_Leg", 0xFFFFFFEC, ini); *((DWORD*)0x51096C) = GetPrivateProfileIntA("Misc", "BodyHit_Eyes", 0xFFFFFFC4, ini); *((DWORD*)0x510970) = GetPrivateProfileIntA("Misc", "BodyHit_Groin", 0xFFFFFFE2, ini); - *((DWORD*)0x510974) = GetPrivateProfileIntA("Misc", "BodyHit_Uncalled", 0x00000000, ini); + *((DWORD*)0x510974) = GetPrivateProfileIntA("Misc", "BodyHit_Torso", 0x00000000, ini); //skillpoints per level mod SafeWrite8(0x43C27a, 5); } diff --git a/sfall/ddraw2.cpp b/sfall/ddraw2.cpp index afd476f0..e5cacfa5 100644 --- a/sfall/ddraw2.cpp +++ b/sfall/ddraw2.cpp @@ -20,6 +20,7 @@ #include #include "ddraw.h" +#include "FalloutEngine.h" #include "Graphics.h" #include "Version.h" #include "input.h" @@ -173,8 +174,7 @@ int _stdcall LoadShader(const char* path) { if(strstr(path, "..")) return -1; if(strstr(path, ":")) return -1; char buf[MAX_PATH]; - strcpy_s(buf, "data\\shaders\\"); - strcat_s(buf, path); + sprintf(buf, "%s\\shaders\\%s", *(char**)_patches, path); for(DWORD d=0;dGetString(buf, &name))) break; - sprintf_s(buf, "data\\art\\stex\\%s", name); + sprintf_s(buf, "%s\\art\\stex\\%s", *(char**)_patches, name); if(FAILED(D3DXCreateTextureFromFileA(d3d9Device,buf,&tex))) continue; sprintf_s(buf, "tex%d", i); shader.Effect->SetTexture(buf, tex); diff --git a/sfall/heads.cpp b/sfall/heads.cpp index 61c65372..e8192284 100644 --- a/sfall/heads.cpp +++ b/sfall/heads.cpp @@ -87,14 +87,11 @@ static void LoadFrm(Frm* frm) { tex_citr itr=texMap.find(frm->key); if(itr==texMap.end()) { //Load textures - char buf[MAX_PATH], buf2[MAX_PATH]; - strcpy(buf, "data\\art\\heads\\"); - strncat(buf, frm->path, 8); - strcat(buf, "\\%d.png"); + char buf[MAX_PATH]; IDirect3DTexture9** textures=new IDirect3DTexture9*[frm->frames]; - for(int i=0;iframes;i++) { - sprintf(buf2, buf, i); - if(FAILED(D3DXCreateTextureFromFileExA(d3d9Device, buf2, 0, 0, 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0, &textures[i]))) { + for (int i = 0; i < frm->frames; i++) { + sprintf(buf, "%s\\art\\heads\\%s\\%d.png", *(char**)_patches, frm->path, i); + if (FAILED(D3DXCreateTextureFromFileExA(d3d9Device, buf, 0, 0, 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0, &textures[i]))) { for(int j=0;jRelease(); delete[] textures; frm->broken=1; @@ -181,9 +178,10 @@ skip: } void HeadsInit() { - if(!GetPrivateProfileInt("Graphics", "Use32BitHeadGraphics", 0, ini)) return; - HookCall(0x44AFB4, &TransTalkHook); - HookCall(0x44B00B, &TransTalkHook); - MakeCall(0x44AD01, &DrawFrmHook, true); - MakeCall(0x447294, &EndSpeechHook, true); + if (GetPrivateProfileInt("Graphics", "Use32BitHeadGraphics", 0, ini)) { + HookCall(0x44AFB4, &TransTalkHook); + HookCall(0x44B00B, &TransTalkHook); + MakeCall(0x44AD01, &DrawFrmHook, true); + MakeCall(0x447294, &EndSpeechHook, true); + } } diff --git a/sfall/movies.cpp b/sfall/movies.cpp index 080685ed..339aa082 100644 --- a/sfall/movies.cpp +++ b/sfall/movies.cpp @@ -266,10 +266,14 @@ static void __declspec(naked) PlayFrameHook2() { static DWORD _stdcall PlayMovieHook2(DWORD id) { //Get file path in unicode wchar_t path[MAX_PATH]; - wcscpy_s(path, L"data\\art\\cuts\\"); - DWORD len=wcslen(path); - char* movie=&MoviePaths[id*65] - len; - while(movie[len]) { path[len]=movie[len]; len++; } + char* master_patches = *(char**)_patches; + DWORD len = 0; + while (master_patches[len]) { path[len] = master_patches[len]; len++; } + path[len] = 0; + wcscat_s(path, L"\\art\\cuts\\"); + len = wcslen(path); + char* movie = &MoviePaths[id*65] - len; + while (movie[len]) { path[len] = movie[len]; len++; } wcscpy_s(&path[len-3], 5, L"avi"); //Check for existance of file