From 46850a353b23207c085509dd91905f73295c8933 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 20 Jan 2019 22:13:30 +0800 Subject: [PATCH] Corrected code in FileSystem.cpp (from Mr.Stalin) Added fix for db_freadInt_ engine function from BugFixes.cpp when enabling UseFileSystemOverride. --- sfall/Modules/BugFixes.cpp | 4 +-- sfall/Modules/FileSystem.cpp | 50 +++++++++++++++++++++++++--------- sfall/Modules/FileSystem.h | 2 +- sfall/Modules/LoadGameHook.cpp | 2 +- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index a2d79870..3594ee24 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -2200,8 +2200,8 @@ void BugFixes::init() // number of values (for chem_primary_desire) MakeJump(0x42C12C, config_get_values_hack); - // Fix returned result value - HookCall(0x4C6162, db_freadInt_hook); // TODO: Resolve conflict in FileSystem.cpp + // Fix returned result value when the file is missing + HookCall(0x4C6162, db_freadInt_hook); } } diff --git a/sfall/Modules/FileSystem.cpp b/sfall/Modules/FileSystem.cpp index 7a2d9b90..60f43ac0 100644 --- a/sfall/Modules/FileSystem.cpp +++ b/sfall/Modules/FileSystem.cpp @@ -57,19 +57,22 @@ std::vector files; static DWORD loadedFiles = 0; // used for internal sfall data bool FileSystem::UsingFileSystem = false; -static void _stdcall xfclose(sFile* file) { +static long _stdcall xfclose(sFile* file) { delete file->opnFile; delete file; + return 0; } static void __declspec(naked) asm_xfclose(sFile* file) { __asm { cmp [eax], 3; // byte jnz end; - pushadc; + push edx; + push ecx; push eax; call xfclose; - popadc; + pop ecx; + pop edx; retn; end: jmp fo::funcoffs::xfclose_; @@ -259,6 +262,25 @@ end: } } +static __declspec(naked) int asm_xfread_fix(void* buf, int elsize, int count, sFile* file) { + __asm { + cmp [ecx], 3; + jnz end; + push ebx; // count + push eax; // buf + call xfread; // ecx - file, edx - elsize + retn; +end: + call fo::funcoffs::xfread_; + // fix + test eax, eax; + jnz skip; + dec eax; +skip: + retn; + } +} + static int __fastcall xfwrite(sFile* file, int elsize, const void* buf, int count) { return 0; } @@ -388,7 +410,7 @@ end: } } -void FileSystemReset() { +static void FileSystemReset() { if (files.empty()) return; for (DWORD i = loadedFiles; i < files.size(); i++) { if (files[i].data) delete[] files[i].data; @@ -415,7 +437,6 @@ void FileSystem::Save(HANDLE h) { } static void FileSystemLoad() { - FileSystemReset(); char buf[MAX_PATH]; GetSavePath(buf, "fs"); @@ -448,11 +469,7 @@ static void __declspec(naked) FSLoadHook() { } } -void FileSystemInit() { - FileSystem::UsingFileSystem = true; - - MakeJump(0x47CCE2, FSLoadHook); - +static void FileSystemOverride() { HookCalls(asm_xfclose, {0x4C5DBD, 0x4C5EA5, 0x4C5EB4}); HookCalls(asm_xfopen, {0x4C5DA9, 0x4C5E16, 0x4C5EC8}); @@ -466,7 +483,7 @@ void FileSystemInit() { HookCall(0x4C5FF4, asm_xfungetc); HookCalls(asm_xfread, {0x4C5E5C, 0x4C5E8A, 0x4C5E9E, 0x4C603D, 0x4C6076, 0x4C60AA}); - HookCall(0x4C6162, asm_xfread); // for fix + HookCall(0x4C6162, asm_xfread_fix); // with bug fix from BugFixes.cpp HookCall(0x4C60B8, asm_xfwrite); HookCall(0x4C60C0, asm_xfseek); @@ -477,7 +494,7 @@ void FileSystemInit() { HookCalls(asm_xfilelength, {0x4C5DB4, 0x4C5E2D, 0x4C68BC}); } -DWORD NewFile(fsFile &file, const char* path, int size) { +static DWORD NewFile(fsFile &file, const char* path, int size) { strcpy_s(file.name, path); file.length = size; file.wpos = 0; @@ -679,10 +696,17 @@ void _stdcall FSresize(DWORD id, DWORD size) { delete[] buf; } +bool FileSystem::IsEmpty() { + return (int)(files.size() - loadedFiles) <= 0; +} + void FileSystem::init() { if (GetConfigInt("Misc", "UseFileSystemOverride", 0)) { - FileSystemInit(); + FileSystemOverride(); + UsingFileSystem = true; } + MakeJump(0x47CCE2, FSLoadHook); // LoadGame_ + LoadGameHook::OnGameReset() += FileSystemReset; } diff --git a/sfall/Modules/FileSystem.h b/sfall/Modules/FileSystem.h index 5e933861..83c47826 100644 --- a/sfall/Modules/FileSystem.h +++ b/sfall/Modules/FileSystem.h @@ -31,6 +31,7 @@ public: static bool UsingFileSystem; // save FileSystem data to a save game file static void Save(HANDLE h); + static bool IsEmpty(); }; DWORD _stdcall FScreate(const char* path, int size); @@ -40,7 +41,6 @@ DWORD _stdcall FSfind(const char* path); void _stdcall FSwrite_byte(DWORD id, int data); void _stdcall FSwrite_short(DWORD id, int data); void _stdcall FSwrite_int(DWORD id, int data); -//void _stdcall fs_write_float(DWORD id, int data); void _stdcall FSwrite_string(DWORD id, const char* data); void _stdcall FSwrite_bstring(DWORD id, const char* data); int _stdcall FSread_byte(DWORD id); diff --git a/sfall/Modules/LoadGameHook.cpp b/sfall/Modules/LoadGameHook.cpp index 522fa6fb..a46f8caf 100644 --- a/sfall/Modules/LoadGameHook.cpp +++ b/sfall/Modules/LoadGameHook.cpp @@ -142,7 +142,7 @@ static void _stdcall SaveGame2() { CloseHandle(h); } - if (!FileSystem::UsingFileSystem) return; + if (FileSystem::IsEmpty()) return; GetSavePath(buf, "fs"); h = CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); if (h != INVALID_HANDLE_VALUE) {