From 2c36ad9a2a01a38922aa910344f118ffbd45ef70 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Mon, 5 Oct 2020 10:26:39 +0800 Subject: [PATCH] Removed InterfaceDontMoveOnTop from ddraw.ini (always enabled) Added a fix to prevent toggling the cursor for a Transparent window. --- artifacts/ddraw.ini | 3 --- sfall/FalloutEngine.cpp | 27 +++++++++++++++------------ sfall/FalloutEngine.h | 5 +++-- sfall/Graphics.cpp | 26 +++++++++++++++----------- sfall/Interface.cpp | 11 +++++++---- sfall/MiscPatches.cpp | 4 ++-- 6 files changed, 42 insertions(+), 34 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 2719522e..1d9c8c35 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -713,9 +713,6 @@ PartyMemberExtraInfo=0 ;Set to 2 to also skip loading the game/combat difficulty settings SkipLoadingGameSettings=0 -;Set to 1 to prevent the inventory/loot/automap interfaces from being placed on top of other script-created windows -InterfaceDontMoveOnTop=0 - ;Overrides the global variable number used to show the special death message of the Modoc toilet explosion ;Set to -1 to disable the special death message when the global variable is set SpecialDeathGVAR=491 diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index dec18634..400a7fb9 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -1376,19 +1376,22 @@ long GetScriptLocalVars(long sid) { return (script) ? script->numLocalVars : 0; } -// Returns window ID by x/y coordinate (hidden windows are ignored) -long __fastcall GetTopWindowID(long xPos, long yPos) { - WINinfo* win = nullptr; - long countWin = *ptr_num_windows - 1; - for (int n = countWin; n >= 0; n--) { - win = ptr_window[n]; - if (xPos >= win->wRect.left && xPos <= win->wRect.right && yPos >= win->wRect.top && yPos <= win->wRect.bottom) { - if (!(win->flags & WinFlags::Hidden)) { - break; +// Returns window by x/y coordinate (hidden windows are ignored) +WINinfo* __fastcall GetTopWindowAtPos(long xPos, long yPos, bool bypassTrans) { + long num = *ptr_num_windows - 1; + if (num) { + int cflags = WinFlags::Hidden; + if (bypassTrans) cflags |= WinFlags::Transparent; + do { + WINinfo* win = ptr_window[num]; + if (xPos >= win->wRect.left && xPos <= win->wRect.right && yPos >= win->wRect.top && yPos <= win->wRect.bottom) { + if (!(win->flags & cflags)) { + return win; + } } - } + } while (--num); } - return win->wID; + return ptr_window[0]; } static long GetRangeTileNumbers(long sourceTile, long radius, long &outEnd) { @@ -1558,7 +1561,7 @@ void __stdcall PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD y } } -void __stdcall PrintTextFM(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) { +void __stdcall PrintTextFM(const char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) { DWORD posOffset = yPos * toWidth + xPos; __asm { xor eax, eax; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index a3b6ae71..4e2deef9 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -1302,7 +1302,8 @@ long __fastcall IsRadInfluence(); // Returns the number of local variables of the object script long GetScriptLocalVars(long sid); -long __fastcall GetTopWindowID(long xPos, long yPos); +// Returns window by x/y coordinate (hidden windows are ignored) +WINinfo* __fastcall GetTopWindowAtPos(long xPos, long yPos, bool bypassTrans = false); // Returns an array of objects within the specified radius from the source tile void GetObjectsTileRadius(std::vector &objs, long sourceTile, long radius, long elev, long type = -1); @@ -1327,7 +1328,7 @@ void ClearWindow(long winID, bool refresh = true); // Print text to surface void __stdcall PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface); -void __stdcall PrintTextFM(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface); +void __stdcall PrintTextFM(const char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface); // gets the height of the currently selected font DWORD __stdcall GetTextHeight(); diff --git a/sfall/Graphics.cpp b/sfall/Graphics.cpp index e198bb1d..b3c3c1c3 100644 --- a/sfall/Graphics.cpp +++ b/sfall/Graphics.cpp @@ -867,8 +867,7 @@ public: if (isPrimary) { if (GPUBlt) { D3DLOCKED_RECT buf; - HRESULT hr = mainTex->LockRect(0, &buf, a, 0); - if (hr) goto surface; // lock failed, use old method + if (mainTex->LockRect(0, &buf, a, 0)) goto surface; // fail to lock, use old method mainTexLock = true; @@ -1275,7 +1274,7 @@ static void __forceinline UpdateDDSurface(BYTE* surface, int width, int height, primaryDDSurface->Lock(&lockRect, &desc, 0, 0); - BufToBuf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch); // + (desc.lPitch * rect->top) + rect->left + BufToBuf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch); //+ (desc.lPitch * rect->top) + rect->left primaryDDSurface->Unlock(desc.lpSurface); } @@ -1297,12 +1296,17 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* int w = updateRect->right - updateRect->left + 1; if (*ptr_mouse_is_hidden || !MouseIn(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) { + /*__asm { + mov eax, win; + mov edx, updateRect; + call GNW_button_refresh_; + }*/ if (!DeviceLost) { int h = (updateRect->bottom - updateRect->top) + 1; UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area } } else { - //fo::func::mouse_show(); + MouseShow(); // for updating background cursor area RECT mouseRect; __asm { lea eax, mouseRect; @@ -1313,11 +1317,11 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* mov rects, eax; } while (rects) { // updates everything except the cursor area - //__asm { - // mov eax, win; - // mov edx, rects; - // call GNW_button_refresh_; - //} + /*__asm { + mov eax, win; + mov edx, rects; + call GNW_button_refresh_; + }*/ if (!DeviceLost) { int wRect = (rects->wRect.right - rects->wRect.left) + 1; int hRect = (rects->wRect.bottom - rects->wRect.top) + 1; @@ -1414,7 +1418,7 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* } } -static __declspec(naked) void GNW_win_refresh_hack(void* from, int widthFrom, int heightFrom, int xFrom, int yFrom, int width, int height, int x, int y) { +static __declspec(naked) void GNW_win_refresh_hack() { __asm { push ebx; // toBuffer mov ecx, eax; @@ -1484,7 +1488,7 @@ void GraphicsInit() { SafeWrite16(0x4D5D46, 0x9090); // win_init_ (create screen_buffer) if (GraphicsMode) { // custom implementation of the GNW_win_refresh function - MakeJump(0x4D6FD9, GNW_win_refresh_hack); + MakeJump(0x4D6FD9, GNW_win_refresh_hack, 1); SafeWrite16(0x4D75E6, 0x9090); // win_clip_ (remove _buffering checking) } else { // for default or HRP graphics mode SafeWrite8(0x4D5DAB, 0x1D); // ecx > ebx (enable _buffering) diff --git a/sfall/Interface.cpp b/sfall/Interface.cpp index eb4b4f9e..ad1cd2b7 100644 --- a/sfall/Interface.cpp +++ b/sfall/Interface.cpp @@ -550,8 +550,11 @@ static long gmouse_handle_event_hook() { static void __declspec(naked) gmouse_bk_process_hook() { __asm { - mov ecx, eax; - jmp GetTopWindowID; + push 1; // bypass Transparent + mov ecx, eax; + call GetTopWindowAtPos; + mov eax, [eax]; // wID + retn; } } @@ -577,8 +580,8 @@ void InterfaceInit() { WorldMapInterfacePatch(); SpeedInterfaceCounterAnimsPatch(); - // Fix for interface windows with 'Hidden' and 'ScriptWindow' flags - // Hidden - will not toggle the mouse cursor when the cursor hovers over a hidden window + // Fix for interface windows with 'Transparent', 'Hidden' and 'ScriptWindow' flags + // Transparent/Hidden - will not toggle the mouse cursor when the cursor hovers over a transparent/hidden window // ScriptWindow - prevents the player from moving when clicking on the window if the 'Transparent' flag is not set HookCall(0x44B737, gmouse_bk_process_hook); // InterfaceGmouseHandleHook will be run before game initialization diff --git a/sfall/MiscPatches.cpp b/sfall/MiscPatches.cpp index 6554cbd4..3e6f1481 100644 --- a/sfall/MiscPatches.cpp +++ b/sfall/MiscPatches.cpp @@ -636,12 +636,12 @@ static void SkipLoadingGameSettingsPatch() { } static void InterfaceDontMoveOnTopPatch() { - if (GetConfigInt("Misc", "InterfaceDontMoveOnTop", 0)) { // TODO: remove option? (obsolete) + //if (GetConfigInt("Misc", "InterfaceDontMoveOnTop", 0)) { dlog("Applying no MoveOnTop flag for interface patch.", DL_INIT); SafeWrite8(0x46ECE9, WinFlags::Exclusive); // Player Inventory/Loot/UseOn SafeWrite8(0x41B966, WinFlags::Exclusive); // Automap dlogr(" Done", DL_INIT); - } + //} } static void UseWalkDistancePatch() {