From b8a77d77fb20fe143f3ff6e7afd9e5537f2bf07b Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 23 Oct 2018 11:50:55 +0800 Subject: [PATCH] Added missing functions from the source library ddraw.dll to export from sfall (from Mr.Stalin) Simplified the code in SuperSave.cpp. Minor edits to ddraw.ini. --- artifacts/ddraw.ini | 3 +- sfall/QuestList.cpp | 6 +-- sfall/SuperSave.cpp | 23 ++++------- sfall/ddraw.cpp | 97 +++++++++++++++++++++++++++++++++++++++++---- sfall/exports.def | 28 +++++++++++-- sfall/main.cpp | 44 +++++++++++++++++++- sfall/main.h | 26 ++++++++++++ 7 files changed, 194 insertions(+), 33 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index ed7e9bf6..c6d00657 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -76,7 +76,6 @@ Use32BitHeadGraphics=0 AllowDShowMovies=0 ;Fade effect time length percentage modifier -;Default is 100. Larger values make it slower, smaller values make it faster FadeMultiplier=100 ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX @@ -159,7 +158,7 @@ ReloadWeaponKey=0 ;A key to hold down to let you move/drop a whole stack of items at once without the 'Move Items' window ;Set to 0 if you don't want to use a modifier key, or a DX scancode otherwise -ItemFastMoveKey=0x1d +ItemFastMoveKey=29 ;Set to 1 to skip the 'Move Items' window when taking items from containers or corpses and not holding down ItemFastMoveKey ;Requires ItemFastMoveKey to be enabled diff --git a/sfall/QuestList.cpp b/sfall/QuestList.cpp index d184f7f3..0b3564d9 100644 --- a/sfall/QuestList.cpp +++ b/sfall/QuestList.cpp @@ -299,8 +299,7 @@ skip: } } -static DWORD __fastcall ActionButtons(register DWORD key) -{ +static DWORD __fastcall ActionButtons(register DWORD key) { buttonsPressed = false; if (key == 0x300) { // up if (curent_quest_page == 0) return -1; @@ -324,8 +323,7 @@ static DWORD __fastcall ActionButtons(register DWORD key) return -1; } -static void __declspec(naked) pipboy_hack_action() -{ +static void __declspec(naked) pipboy_hack_action() { __asm { test calledflag, 0xFF; jz skip; diff --git a/sfall/SuperSave.cpp b/sfall/SuperSave.cpp index 4209392b..7e80fb6b 100644 --- a/sfall/SuperSave.cpp +++ b/sfall/SuperSave.cpp @@ -130,11 +130,8 @@ void SetPageNum() { unsigned int TxtWidth = 0; DWORD NewTick = 0, OldTick = 0; - int button = 0; - int exitFlag = 0; - char blip = '_'; - char Number[5]; - int numpos = 0; + int button = 0, exitFlag = 0, numpos = 0; + char Number[5], blip = '_'; DWORD tempPageOffset = -1; @@ -355,13 +352,11 @@ static void __declspec(naked) AddPageOffset01(void) { // getting info for the 10 currently displayed save slots from save.dats static void __declspec(naked) AddPageOffset02(void) { __asm { - pop edx // pop ret addr - mov eax, 0x50A514 // ASCII "SAVE.DAT" - push eax - lea eax, dword ptr ds:[ebx+1] - add eax, LSPageOffset // add page num offset - push edx // push ret addr - ret + push 0x50A514; // ASCII "SAVE.DAT" + lea eax, [ebx + 1]; + add eax, LSPageOffset; // add page num offset + mov edx, 0x47E5E9; // ret addr + jmp edx; } } @@ -402,9 +397,7 @@ void EnableSuperSaving() { MakeCall(AddPageOffset01Addrs[i], AddPageOffset01); } - MakeCall(0x47E5E1, AddPageOffset02); - SafeWrite16(0x47E5E6, 0x9090); - SafeWrite8(0x47E5E8, 0x90); + MakeJump(0x47E5E1, AddPageOffset02); MakeCall(0x47E756, AddPageOffset03); } diff --git a/sfall/ddraw.cpp b/sfall/ddraw.cpp index e1210364..c559a2be 100644 --- a/sfall/ddraw.cpp +++ b/sfall/ddraw.cpp @@ -18,15 +18,96 @@ #include "main.h" +extern ddrawDll ddraw; + typedef HRESULT (_stdcall *DDrawCreateProc)(void* a, void* b, void* c); HRESULT _stdcall FakeDirectDrawCreate(void* a, void* b, void* c) { - char path[MAX_PATH]; - GetSystemDirectoryA(path,MAX_PATH); - strcat_s(path, "\\ddraw.dll"); - HMODULE ddraw=LoadLibraryA(path); - if(!ddraw||ddraw==INVALID_HANDLE_VALUE) return -1; - DDrawCreateProc proc=(DDrawCreateProc)GetProcAddress(ddraw, "DirectDrawCreate"); - if(!proc) return -1; - return proc(a,b,c); + DDrawCreateProc proc = (DDrawCreateProc)ddraw.DirectDrawCreate; + if (!proc) return -1; + return proc(a, b, c); +} + +__declspec(naked) void FakeAcquireDDThreadLock() { + _asm jmp [ddraw.AcquireDDThreadLock]; +} + +__declspec(naked) void FakeCheckFullscreen() { + _asm jmp [ddraw.CheckFullscreen]; +} + +__declspec(naked) void FakeCompleteCreateSysmemSurface() { + _asm jmp [ddraw.CompleteCreateSysmemSurface]; +} + +__declspec(naked) void FakeD3DParseUnknownCommand() { + _asm jmp [ddraw.D3DParseUnknownCommand]; +} + +__declspec(naked) void FakeDDGetAttachedSurfaceLcl() { + _asm jmp [ddraw.DDGetAttachedSurfaceLcl]; +} + +__declspec(naked) void FakeDDInternalLock() { + _asm jmp [ddraw.DDInternalLock]; +} + +__declspec(naked) void FakeDDInternalUnlock() { + _asm jmp [ddraw.DDInternalUnlock]; +} + +__declspec(naked) void FakeDSoundHelp() { + _asm jmp [ddraw.DSoundHelp]; +} + +__declspec(naked) void FakeDirectDrawCreateClipper() { + _asm jmp [ddraw.DirectDrawCreateClipper]; +} + +__declspec(naked) void FakeDirectDrawCreateEx() { + _asm jmp [ddraw.DirectDrawCreateEx]; +} + +__declspec(naked) void FakeDirectDrawEnumerateA() { + _asm jmp [ddraw.DirectDrawEnumerateA]; +} + +__declspec(naked) void FakeDirectDrawEnumerateExA() { + _asm jmp [ddraw.DirectDrawEnumerateExA]; +} + +__declspec(naked) void FakeDirectDrawEnumerateExW() { + _asm jmp [ddraw.DirectDrawEnumerateExW]; +} + +__declspec(naked) void FakeDirectDrawEnumerateW() { + _asm jmp [ddraw.DirectDrawEnumerateW]; +} + +//__declspec(naked) void FakeDllCanUnloadNow() { +// _asm jmp [ddraw.DllCanUnloadNow]; +//} + +//__declspec(naked) void FakeDllGetClassObject() { +// _asm jmp [ddraw.DllGetClassObject]; +//} + +__declspec(naked) void FakeGetDDSurfaceLocal() { + _asm jmp [ddraw.GetDDSurfaceLocal]; +} + +__declspec(naked) void FakeGetOLEThunkData() { + _asm jmp [ddraw.GetOLEThunkData]; +} + +__declspec(naked) void FakeGetSurfaceFromDC() { + _asm jmp [ddraw.GetSurfaceFromDC]; +} + +__declspec(naked) void FakeRegisterSpecialCase() { + _asm jmp [ddraw.RegisterSpecialCase]; +} + +__declspec(naked) void FakeReleaseDDThreadLock() { + _asm jmp [ddraw.ReleaseDDThreadLock]; } diff --git a/sfall/exports.def b/sfall/exports.def index 52433d71..29acfccc 100644 --- a/sfall/exports.def +++ b/sfall/exports.def @@ -1,6 +1,28 @@ LIBRARY ddraw EXPORTS -DirectDrawCreate=FakeDirectDrawCreate -DirectDrawCreat2=FakeDirectDrawCreate2 -DirectInputCreateA=FakeDirectInputCreate +AcquireDDThreadLock = FakeAcquireDDThreadLock @1 +CheckFullscreen = FakeCheckFullscreen @2 +CompleteCreateSysmemSurface = FakeCompleteCreateSysmemSurface @3 +D3DParseUnknownCommand = FakeD3DParseUnknownCommand @4 +DDGetAttachedSurfaceLcl = FakeDDGetAttachedSurfaceLcl @5 +DDInternalLock = FakeDDInternalLock @6 +DDInternalUnlock = FakeDDInternalUnlock @7 +DSoundHelp = FakeDSoundHelp @8 +DirectDrawCreate = FakeDirectDrawCreate @9 +DirectDrawCreateClipper = FakeDirectDrawCreateClipper @10 +DirectDrawCreateEx = FakeDirectDrawCreateEx @11 +DirectDrawEnumerateA = FakeDirectDrawEnumerateA @12 +DirectDrawEnumerateExA = FakeDirectDrawEnumerateExA @13 +DirectDrawEnumerateExW = FakeDirectDrawEnumerateExW @14 +DirectDrawEnumerateW = FakeDirectDrawEnumerateW @15 +;DllCanUnloadNow = FakeDllCanUnloadNow @16 +;DllGetClassObject = FakeDllGetClassObject @17 +GetDDSurfaceLocal = FakeGetDDSurfaceLocal @18 +GetOLEThunkData = FakeGetOLEThunkData @19 +GetSurfaceFromDC = FakeGetSurfaceFromDC @20 +RegisterSpecialCase = FakeRegisterSpecialCase @21 +ReleaseDDThreadLock = FakeReleaseDDThreadLock @22 + +DirectDrawCreat2 = FakeDirectDrawCreate2 +DirectInputCreateA = FakeDirectInputCreate diff --git a/sfall/main.cpp b/sfall/main.cpp index 0a64f17b..d882f6a6 100644 --- a/sfall/main.cpp +++ b/sfall/main.cpp @@ -1566,8 +1566,50 @@ static void CompatModeCheck(HKEY root, const char* filepath, int extra) { } } +ddrawDll ddraw; +static bool LoadOriginalDll(DWORD dwReason) { + switch (dwReason) { + case DLL_PROCESS_ATTACH: + char path[MAX_PATH]; + CopyMemory(path + GetSystemDirectoryA(path , MAX_PATH - 10), "\\ddraw.dll", 11); // path to original dll + ddraw.dll = LoadLibrary(path); + if (!ddraw.dll || ddraw.dll == INVALID_HANDLE_VALUE) { + MessageBox(0, "Cannot load the original ddraw.dll library.", "sfall", MB_ICONERROR); + ExitProcess(-1); + break; + } + ddraw.AcquireDDThreadLock = GetProcAddress(ddraw.dll, "AcquireDDThreadLock"); + ddraw.CheckFullscreen = GetProcAddress(ddraw.dll, "CheckFullscreen"); + ddraw.CompleteCreateSysmemSurface = GetProcAddress(ddraw.dll, "CompleteCreateSysmemSurface"); + ddraw.D3DParseUnknownCommand = GetProcAddress(ddraw.dll, "D3DParseUnknownCommand"); + ddraw.DDGetAttachedSurfaceLcl = GetProcAddress(ddraw.dll, "DDGetAttachedSurfaceLcl"); + ddraw.DDInternalLock = GetProcAddress(ddraw.dll, "DDInternalLock"); + ddraw.DDInternalUnlock = GetProcAddress(ddraw.dll, "DDInternalUnlock"); + ddraw.DSoundHelp = GetProcAddress(ddraw.dll, "DSoundHelp"); + ddraw.DirectDrawCreateClipper = GetProcAddress(ddraw.dll, "DirectDrawCreateClipper"); + ddraw.DirectDrawCreate = GetProcAddress(ddraw.dll, "DirectDrawCreate"); + ddraw.DirectDrawCreateEx = GetProcAddress(ddraw.dll, "DirectDrawCreateEx"); + ddraw.DirectDrawEnumerateA = GetProcAddress(ddraw.dll, "DirectDrawEnumerateA"); + ddraw.DirectDrawEnumerateExA = GetProcAddress(ddraw.dll, "DirectDrawEnumerateExA"); + ddraw.DirectDrawEnumerateExW = GetProcAddress(ddraw.dll, "DirectDrawEnumerateExW"); + ddraw.DirectDrawEnumerateW = GetProcAddress(ddraw.dll, "DirectDrawEnumerateW"); + //ddraw.DllCanUnloadNow = GetProcAddress(ddraw.dll, "DllCanUnloadNow"); + //ddraw.DllGetClassObject = GetProcAddress(ddraw.dll, "DllGetClassObject"); + ddraw.GetDDSurfaceLocal = GetProcAddress(ddraw.dll, "GetDDSurfaceLocal"); + ddraw.GetOLEThunkData = GetProcAddress(ddraw.dll, "GetOLEThunkData"); + ddraw.GetSurfaceFromDC = GetProcAddress(ddraw.dll, "GetSurfaceFromDC"); + ddraw.RegisterSpecialCase = GetProcAddress(ddraw.dll, "RegisterSpecialCase"); + ddraw.ReleaseDDThreadLock = GetProcAddress(ddraw.dll, "ReleaseDDThreadLock"); + return true; + case DLL_PROCESS_DETACH: + FreeLibrary(ddraw.dll); + break; + } + return false; +} + bool _stdcall DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { - if (dwReason == DLL_PROCESS_ATTACH) { + if (LoadOriginalDll(dwReason)) { // enabling debugging features IsDebug = (GetPrivateProfileIntA("Debugging", "Enable", 0, ".\\ddraw.ini") != 0); if (IsDebug) { diff --git a/sfall/main.h b/sfall/main.h index ca3b1ad6..6a603fe4 100644 --- a/sfall/main.h +++ b/sfall/main.h @@ -23,6 +23,32 @@ #include "SafeWrite.h" #include "Logging.h" +struct ddrawDll { + HMODULE dll; + FARPROC DirectDrawEnumerateExA; + FARPROC DirectDrawCreate; + FARPROC DirectDrawCreateEx; + FARPROC AcquireDDThreadLock; + FARPROC ReleaseDDThreadLock; + FARPROC CheckFullscreen; + FARPROC CompleteCreateSysmemSurface; + FARPROC D3DParseUnknownCommand; + FARPROC DDGetAttachedSurfaceLcl; + FARPROC DDInternalLock; + FARPROC DDInternalUnlock; + FARPROC DSoundHelp; + FARPROC DirectDrawCreateClipper; + FARPROC DirectDrawEnumerateA; + FARPROC DirectDrawEnumerateExW; + FARPROC DirectDrawEnumerateW; + //FARPROC DllCanUnloadNow; + //FARPROC DllGetClassObject; + FARPROC GetDDSurfaceLocal; + FARPROC GetOLEThunkData; + FARPROC GetSurfaceFromDC; + FARPROC RegisterSpecialCase; +}; + // global flag, indicating that debugging features of Sfall are enabled #ifndef NO_SFALL_DEBUG extern bool IsDebug;