diff --git a/sfall/FalloutEngine/FunctionOffsets_def.h b/sfall/FalloutEngine/FunctionOffsets_def.h index 7a6160fe..760f24f3 100644 --- a/sfall/FalloutEngine/FunctionOffsets_def.h +++ b/sfall/FalloutEngine/FunctionOffsets_def.h @@ -509,6 +509,7 @@ FUNC(proto_dude_update_gender_, 0x49F984) FUNC(proto_get_msg_info_, 0x49EAA4) FUNC(proto_list_str_, 0x49E758) FUNC(proto_make_path_, 0x49E270) +FUNC(proto_name_, 0x49EAFC) FUNC(proto_ptr_, 0x4A2108) // eax - PID, edx - int** - pointer to a pointer to a proto struct FUNC(pushLongStack_, 0x46736C) FUNC(qsort_, 0x4F05B6) diff --git a/sfall/FalloutEngine/VariableOffsets.h b/sfall/FalloutEngine/VariableOffsets.h index 4b53562d..397f4c59 100644 --- a/sfall/FalloutEngine/VariableOffsets.h +++ b/sfall/FalloutEngine/VariableOffsets.h @@ -116,6 +116,7 @@ #define FO_VAR_gmovie_played_list 0x596C78 #define FO_VAR_GNW_win_init_flag 0x51E3E0 #define FO_VAR_GNW95_hDDrawLib 0x51E44C +#define FO_VAR_GNW95_hwnd 0x51E434 // main hwnd window #define FO_VAR_GNW95_isActive 0x51E444 #define FO_VAR_GNW95_repeat_delay 0x51E240 #define FO_VAR_GNW95_repeat_rate 0x51E23C diff --git a/sfall/InputFuncs.cpp b/sfall/InputFuncs.cpp index 7b9a544e..68122ead 100644 --- a/sfall/InputFuncs.cpp +++ b/sfall/InputFuncs.cpp @@ -459,6 +459,11 @@ HRESULT __stdcall FakeDirectInputCreate(HINSTANCE a, DWORD b, IDirectInputA** c, HRESULT hr = proc(a, b, c, d); if (FAILED(hr)) return hr; + // Prevent "Failure initializing input devices" error + if (sfall::Graphics::IsWindowedMode && !sfall::backgroundMouse) { + SetForegroundWindow((HWND)fo::var::getInt(FO_VAR_GNW95_hwnd)); + } + *c = (IDirectInputA*)new sfall::FakeDirectInput(*c); sfall::keyboardLayout = GetKeyboardLayout(0); diff --git a/sfall/Modules/Graphics.cpp b/sfall/Modules/Graphics.cpp index 7c4dea8a..e5f18e4c 100644 --- a/sfall/Modules/Graphics.cpp +++ b/sfall/Modules/Graphics.cpp @@ -34,12 +34,16 @@ namespace sfall { -#define UNUSEDFUNCTION { return DDERR_GENERIC; } -#define SAFERELEASE(a) { if (a) { a->Release(); a = nullptr; } } - //typedef HRESULT (__stdcall *DDrawCreateProc)(void*, IDirectDraw**, void*); //typedef IDirect3D9* (__stdcall *D3DCreateProc)(UINT version); +#define UNUSEDFUNCTION { return DDERR_GENERIC; } +#define SAFERELEASE(a) { if (a) { a->Release(); a = nullptr; } } + +#define ShowMessageBox(text) ShowWindow(window, SW_MINIMIZE); \ + MessageBoxA(window, text, "sfall DirectX 9", MB_TASKMODAL | MB_ICONWARNING); \ + ShowWindow(window, SW_RESTORE) + #if !(NDEBUG) && !(_DEBUG) static LPD3DXFONT font; static RECT fontPosition; @@ -62,6 +66,7 @@ static DWORD gHeight; DWORD Graphics::GPUBlt; DWORD Graphics::mode; +bool Graphics::IsWindowedMode; bool Graphics::PlayAviMovie = false; bool Graphics::AviMovieWidthFit = false; @@ -204,19 +209,14 @@ static void ResetDevice(bool create) { DWORD mThreadFlags = (dShowMovies) ? D3DCREATE_MULTITHREADED : 0; dlog("Creating D3D9 Device...", DL_MAIN); - if (FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE | mThreadFlags, ¶ms, &d3d9Device))) { //D3DCREATE_PUREDEVICE + if (FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE | mThreadFlags, ¶ms, &d3d9Device))) { // D3DCREATE_PUREDEVICE if (FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE | mThreadFlags, ¶ms, &d3d9Device))) { d3d9Device = nullptr; dlogr(" Failed!", DL_MAIN); return; } software = true; - if (params.Windowed) { - MessageBoxA(window, "Failed to create hardware vertex processing device.\nUsing software vertex processing instead.", - "sfall DirectX 9", MB_TASKMODAL | MB_ICONWARNING); - } else { - dlogr(" Failed to create hardware vertex processing device.\nUsing software vertex processing instead.", DL_MAIN); - } + ShowMessageBox("Failed to create hardware vertex processing device.\nUsing software vertex processing instead."); } D3DCAPS9 caps; @@ -245,8 +245,7 @@ static void ResetDevice(bool create) { textureFormat = (A8IsSupported) ? D3DFMT_A8 : D3DFMT_L8; // D3DFMT_A8 - not supported on some older video cards } else { - MessageBoxA(window, "Failed to create shader effects.\nSwitching to CPU for the palette conversion.", - "sfall DirectX 9", MB_TASKMODAL | MB_ICONWARNING); + ShowMessageBox("Failed to create shader effects.\nSwitching to CPU for the palette conversion."); if (mainTex) SAFERELEASE(mainTex); // release D3DFMT_A8 format texture Graphics::GPUBlt = 0; A8IsSupported = false; @@ -256,9 +255,8 @@ static void ResetDevice(bool create) { if (!A8IsSupported && d3d9Device->CreateTexture(ResWidth, ResHeight, 1, 0, textureFormat, D3DPOOL_SYSTEMMEM, &mainTex, 0) != D3D_OK) { textureFormat = D3DFMT_X8R8G8B8; d3d9Device->CreateTexture(ResWidth, ResHeight, 1, 0, textureFormat, D3DPOOL_SYSTEMMEM, &mainTex, 0); - MessageBoxA(window, "Texture format error.\nGPU does not support the D3DFMT_L8 texture format.\nNow CPU is used to convert the palette.\n" - "Set 'GPUBlt' option to CPU to bypass this warning message.", - "sfall DirectX 9", MB_TASKMODAL | MB_ICONWARNING); + ShowMessageBox("Texture format error.\nGPU does not support the D3DFMT_L8 texture format.\nNow CPU is used to convert the palette.\n" + "Set 'GPUBlt' option to CPU to bypass this warning message."); Graphics::GPUBlt = 0; } if (Graphics::GPUBlt == 0) palette = new PALCOLOR[256]; @@ -977,7 +975,7 @@ public: ULONG __stdcall AddRef() { return ++Refs; } - ULONG __stdcall Release() { // called from game on exit + ULONG __stdcall Release() { // called from GNW95_reset_mode_ (on game exit) if (!--Refs) { ScriptShaders::Release(); @@ -1038,7 +1036,13 @@ public: HRESULT __stdcall GetScanLine(LPDWORD) { UNUSEDFUNCTION; } HRESULT __stdcall GetVerticalBlankStatus(LPBOOL) { UNUSEDFUNCTION; } HRESULT __stdcall Initialize(GUID *) { UNUSEDFUNCTION; } - HRESULT __stdcall RestoreDisplayMode() { return DD_OK; } + + HRESULT __stdcall RestoreDisplayMode() { // called from GNW95_reset_mode_ + #ifdef NDEBUG + ShowWindow(window, SW_HIDE); + #endif + return DD_OK; + } HRESULT __stdcall SetCooperativeLevel(HWND a, DWORD b) { // called 0x4CB005 GNW95_init_DirectDraw_ window = a; @@ -1467,6 +1471,7 @@ void Graphics::init() { if (Graphics::mode < 4 || Graphics::mode > 6) { Graphics::mode = 0; } + IsWindowedMode = (mode > 4); if (Graphics::mode) { dlog("Applying DX9 graphics patch.", DL_INIT); diff --git a/sfall/Modules/Graphics.h b/sfall/Modules/Graphics.h index 2d2ba32b..82fa2194 100644 --- a/sfall/Modules/Graphics.h +++ b/sfall/Modules/Graphics.h @@ -37,6 +37,7 @@ public: static DWORD mode; static DWORD GPUBlt; + static bool IsWindowedMode; static long GetGameWidthRes(); static long GetGameHeightRes(); diff --git a/sfall/Modules/ScriptExtender.cpp b/sfall/Modules/ScriptExtender.cpp index fee77b6e..ecd0a9ed 100644 --- a/sfall/Modules/ScriptExtender.cpp +++ b/sfall/Modules/ScriptExtender.cpp @@ -1059,7 +1059,7 @@ void ObjectName::SetName(long sid, const char* name) { const char* __stdcall ObjectName::GetName(fo::GameObject* object) { if (!overrideScrName.empty()) { - std::tr1::unordered_map::iterator name = overrideScrName.find(object->scriptId); + std::tr1::unordered_map::iterator &name = overrideScrName.find(object->scriptId); if (name != overrideScrName.cend()) { return (name->second.length() > 0) ? name->second.c_str() @@ -1121,14 +1121,12 @@ static void __declspec(naked) critter_name_hack_end() { } } -static void __declspec(naked) object_name_hook() { - using namespace fo::Fields; +static void __declspec(naked) item_name_hook() { __asm { - mov edx, [eax + protoId]; - cmp edx, lastItemPid; + cmp eax, lastItemPid; je getLast; - mov lastItemPid, edx; - jmp fo::funcoffs::item_name_; + mov lastItemPid, eax; + jmp fo::funcoffs::proto_name_; getLast: mov eax, ds:[FO_VAR_name_item]; retn; @@ -1219,7 +1217,7 @@ void ScriptExtender::init() { // Tweak for quickly getting last object name MakeCall(0x42D0C4, critter_name_hack_check, 1); MakeCall(0x42D12A, critter_name_hack_end); - HookCall(0x48C901, object_name_hook); + HookCall(0x477AE7, item_name_hook); } }