Added a fix for scripted interface windows

* prevents player's movement when clicking on the window.

* the mouse cursor will not be toggled when the cursor hovers over
a hidden window.

Updated version number.
This commit is contained in:
NovaRain
2019-11-10 18:24:43 +08:00
parent 29da6d7071
commit e62b5c03db
17 changed files with 136 additions and 39 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
;sfall configuration settings
;v3.8.21
;v3.8.22
[Main]
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
+14
View File
@@ -369,6 +369,20 @@ enum RollResult
ROLL_CRITICAL_SUCCESS = 0x3,
};
enum WinButtonFlags : long
{
WIN_OwnerFlag = 0x1,
WIN_UnknownFlag2 = 0x2,
WIN_MoveOnTop = 0x4,
WIN_Hidden = 0x8,
WIN_Exclusive = 0x10,
WIN_Transparent = 0x20,
WIN_UnknownFlag40 = 0x40,
WIN_UnknownFlag80 = 0x80,
WIN_ScriptWindow = 0x100,
WIN_itsButton = 0x10000,
};
enum QueueType : long
{
drug_effect_event = 0, // critter use drug
+2 -2
View File
@@ -157,7 +157,7 @@ void SetPageNum() {
}
// fill over text area with consol black colour
for (unsigned int y = SaveLoadWin->width * 52; y < SaveLoadWin->width * 82; y = y + SaveLoadWin->width) {
for (int y = SaveLoadWin->width * 52; y < SaveLoadWin->width * 82; y = y + SaveLoadWin->width) {
memset(SaveLoadWin->surface + y + 170 - TxtMaxWidth / 2, 0xCF, TxtMaxWidth);
}
@@ -269,7 +269,7 @@ void DrawPageText() {
}
// fill over text area with consol black colour
for (unsigned int y = SaveLoadWin->width * 52; y < SaveLoadWin->width * 82; y = y + SaveLoadWin->width) {
for (int y = SaveLoadWin->width * 52; y < SaveLoadWin->width * 82; y = y + SaveLoadWin->width) {
memset(SaveLoadWin->surface + 50 + y, 0xCF, 240);
}
+15
View File
@@ -53,6 +53,9 @@ DWORD* ptr_curr_font_num = reinterpret_cast<DWORD*>(_curr_font_num)
DWORD* ptr_curr_pc_stat = reinterpret_cast<DWORD*>(_curr_pc_stat);
DWORD* ptr_curr_stack = reinterpret_cast<DWORD*>(_curr_stack);
DWORD* ptr_cursor_line = reinterpret_cast<DWORD*>(_cursor_line);
BYTE* ptr_DARK_GREY_Color = reinterpret_cast<BYTE*>(_DARK_GREY_Color);
BYTE* ptr_DarkGreenColor = reinterpret_cast<BYTE*>(_DarkGreenColor);
BYTE* ptr_DarkGreenGreyColor = reinterpret_cast<BYTE*>(_DarkGreenGreyColor);
DWORD* ptr_dialog_target = reinterpret_cast<DWORD*>(_dialog_target);
DWORD* ptr_dialog_target_is_party = reinterpret_cast<DWORD*>(_dialog_target_is_party);
DWORD* ptr_drugInfoList = reinterpret_cast<DWORD*>(_drugInfoList);
@@ -108,6 +111,7 @@ DWORD* ptr_last_button_winID = reinterpret_cast<DWORD*>(_last_button_wi
DWORD* ptr_last_level = reinterpret_cast<DWORD*>(_last_level);
DWORD* ptr_Level_ = reinterpret_cast<DWORD*>(_Level_);
DWORD* ptr_Lifegiver = reinterpret_cast<DWORD*>(_Lifegiver);
BYTE* ptr_LIGHT_GREY_Color = reinterpret_cast<BYTE*>(_LIGHT_GREY_Color);
DWORD* ptr_lipsFID = reinterpret_cast<DWORD*>(_lipsFID);
DWORD* ptr_list_com = reinterpret_cast<DWORD*>(_list_com);
DWORD* ptr_list_total = reinterpret_cast<DWORD*>(_list_total);
@@ -210,6 +214,7 @@ DWORD* ptr_title_font = reinterpret_cast<DWORD*>(_title_font);
DWORD* ptr_trait_data = reinterpret_cast<DWORD*>(_trait_data);
DWORD* ptr_view_page = reinterpret_cast<DWORD*>(_view_page);
DWORD* ptr_wd_obj = reinterpret_cast<DWORD*>(_wd_obj);
DWORD* ptr_window = reinterpret_cast<DWORD*>(_window); // total 50
BYTE* ptr_WhiteColor = reinterpret_cast<BYTE*>(_WhiteColor);
DWORD* ptr_wmAreaInfoList = reinterpret_cast<DWORD*>(_wmAreaInfoList);
DWORD* ptr_wmLastRndTime = reinterpret_cast<DWORD*>(_wmLastRndTime);
@@ -676,6 +681,7 @@ const DWORD win_draw_ = 0x4D6F5C;
const DWORD win_draw_rect_ = 0x4D6F80;
const DWORD win_enable_button_ = 0x4D9474;
const DWORD win_get_buf_ = 0x4D78B0;
const DWORD win_get_top_win_ = 0x4D78CC;
const DWORD win_hide_ = 0x4D6E64;
const DWORD win_line_ = 0x4D6B24;
const DWORD win_print_ = 0x4D684C;
@@ -1245,3 +1251,12 @@ long __fastcall ItemAddForce(TGameObj* critter, TGameObj* item, long count) {
call item_add_force_;
}
}
long __fastcall MouseClickIn(long x, long y, long x_end, long y_end) {
__asm {
mov eax, ecx;
mov ebx, x_end;
mov ecx, y_end;
call mouse_click_in_;
}
}
+14
View File
@@ -69,6 +69,7 @@
#define _dialogue_head 0x518850
#define _dialogue_state 0x518714
#define _dialogue_switch_mode 0x518718
#define _display_win 0x631E4C
#define _displayMapList 0x41B560
#define _dropped_explosive 0x5190E0
#define _drugInfoList 0x5191CC
@@ -163,6 +164,7 @@
#define _name_sort_list 0x56FCB0
#define _num_game_global_vars 0x5186C4
#define _num_map_global_vars 0x519574
#define _num_windows 0x6ADF24
#define _obj_dude 0x6610B8
#define _obj_seen 0x662445
#define _objectTable 0x639DA0
@@ -244,6 +246,7 @@
#define _trait_data 0x51DB84
#define _view_page 0x664520
#define _wd_obj 0x59E98C
#define _window 0x6ADE58
#define _wmAreaInfoList 0x51DDF8
#define _wmLastRndTime 0x51DEA0
#define _wmMaxMapNum 0x51DE10
@@ -256,10 +259,13 @@
// colors
#define _BlueColor 0x6A38EF
#define _DARK_GREY_Color 0x6A59D8
#define _DarkGreenColor 0x6A3A90
#define _DarkGreenGreyColor 0x6A3DF1
#define _DullPinkColor 0x6AB718
#define _GoodColor 0x6AB4EF
#define _GreenColor 0x6A3CB0
#define _LIGHT_GREY_Color 0x6A76BF
#define _PeanutButter 0x6A82F3
#define _RedColor 0x6AB4D0
#define _WhiteColor 0x6AB8CF
@@ -298,6 +304,9 @@ extern DWORD* ptr_curr_font_num;
extern DWORD* ptr_curr_pc_stat;
extern DWORD* ptr_curr_stack;
extern DWORD* ptr_cursor_line;
extern BYTE* ptr_DARK_GREY_Color;
extern BYTE* ptr_DarkGreenColor;
extern BYTE* ptr_DarkGreenGreyColor;
extern DWORD* ptr_dialog_target;
extern DWORD* ptr_dialog_target_is_party;
extern DWORD* ptr_drugInfoList;
@@ -353,6 +362,7 @@ extern DWORD* ptr_last_button_winID;
extern DWORD* ptr_last_level;
extern DWORD* ptr_Level_;
extern DWORD* ptr_Lifegiver;
extern BYTE* ptr_LIGHT_GREY_Color;
extern DWORD* ptr_lipsFID;
extern DWORD* ptr_list_com;
extern DWORD* ptr_list_total;
@@ -456,6 +466,7 @@ extern DWORD* ptr_title_font;
extern DWORD* ptr_trait_data;
extern DWORD* ptr_view_page;
extern DWORD* ptr_wd_obj;
extern DWORD* ptr_window; // total 50
extern BYTE* ptr_WhiteColor;
extern DWORD* ptr_wmAreaInfoList;
extern DWORD* ptr_wmLastRndTime;
@@ -912,6 +923,7 @@ extern const DWORD win_draw_;
extern const DWORD win_draw_rect_;
extern const DWORD win_enable_button_;
extern const DWORD win_get_buf_;
extern const DWORD win_get_top_win_;
extern const DWORD win_hide_;
extern const DWORD win_line_;
extern const DWORD win_print_;
@@ -1120,3 +1132,5 @@ void __fastcall IntfaceUpdateItems(long animate, long modeLeft, long modeRight);
long __stdcall InvenUnwield(TGameObj* critter, long slot);
long __fastcall ItemAddForce(TGameObj* critter, TGameObj* item, long count);
long __fastcall MouseClickIn(long x, long y, long x_end, long y_end);
+20
View File
@@ -236,6 +236,26 @@ public:
} FrmHeaderData;
#pragma pack(pop)
//for holding window info
#pragma pack(push, 1)
struct WINinfo {
long wID;
long flags;
RECT wRect;
long width;
long height;
long clearColour;
long rand1;
long rand2;
BYTE *surface; // bytes frame data ref to palette
long *buttonsList;
long unknown5; // buttonptr?
long unknown6;
long *menuBar;
long *drawFunc;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct Queue {
DWORD time;
+1 -3
View File
@@ -495,14 +495,12 @@ void DestroyWin(int WinRef) {
}
}
WINinfo *GetWinStruct(int WinRef) {
WINinfo* GetWinStruct(int WinRef) {
WINinfo *winStruct;
__asm {
push edx;
mov eax, WinRef;
call GNW_find_;
mov winStruct, eax;
pop edx;
}
return winStruct;
}
+2 -18
View File
@@ -18,25 +18,9 @@
#pragma once
//for holding window info
typedef struct WINinfo {
DWORD ref;
DWORD flags;
RECT wRect;
DWORD width;
DWORD height;
DWORD clearColour;
DWORD unknown2;
DWORD unknown3;
BYTE *surface; //bytes frame data ref to palette
DWORD buttonListP;
DWORD unknown5; //buttonptr?
DWORD unknown6;
DWORD unknown7;
DWORD drawFuncP;
} WINinfo;
#include "FalloutStructs.h"
WINinfo *GetWinStruct(int WinRef);
WINinfo* GetWinStruct(int WinRef);
void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWORD TxtWidth, DWORD ToWidth, BYTE *ToSurface);
DWORD GetTextWidth(char *TextMsg);
DWORD GetMaxCharWidth();
+50
View File
@@ -17,7 +17,9 @@
*/
#include "main.h"
#include "Define.h"
#include "FalloutEngine.h"
#include "HeroAppearance.h"
static long costAP = -1;
static void __declspec(naked) intface_redraw_items_hack0() {
@@ -203,8 +205,56 @@ static void SpeedInterfaceCounterAnimsPatch() {
}
}
static bool IFACE_BAR_MODE = false;
static long gmouse_handle_event_hook() {
long countWin = *(DWORD*)_num_windows;
long ifaceWin = *ptr_interfaceWindow;
WINinfo* win = nullptr;
for (int n = 1; n < countWin; n++) {
win = (WINinfo*)ptr_window[n];
if ((win->wID == ifaceWin || (win->flags & WIN_ScriptWindow && !(win->flags & WIN_Transparent))) // also check scripted windows
&& !(win->flags & WIN_Hidden)) {
RECT *rect = &win->wRect;
if (MouseClickIn(rect->left, rect->top, rect->right, rect->bottom)) return 0; // 0 - block clicking in the window area
}
}
if (IFACE_BAR_MODE) return 1;
// if IFACE_BAR_MODE is not enabled, check the display_win window area
win = GetWinStruct(*(DWORD*)_display_win);
RECT *rect = &win->wRect;
return MouseClickIn(rect->left, rect->top, rect->right, rect->bottom); // 1 - click in the display_win area
}
static void __declspec(naked) gmouse_bk_process_hook() {
__asm {
call win_get_top_win_;
cmp eax, ds:[_display_win];
jnz checkFlag;
retn;
checkFlag:
call GNW_find_;
cmp [eax + 4], WIN_Hidden; // window flags
jnz skip;
mov eax, ds:[_display_win]; // window is hidden, so return the number of the display_win
skip:
retn;
}
}
void InterfaceGmouseHandleHook() {
if (hrpVersionValid) IFACE_BAR_MODE = *(BYTE*)HRPAddress(0x1006EB0C) != 0;
HookCall(0x44C018, gmouse_handle_event_hook); // replaces hack function from HRP
}
void InterfaceInit() {
DrawActionPointsNumber();
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
// ScriptWindow - prevents player's movement 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
}
+1
View File
@@ -1,3 +1,4 @@
#pragma once
void InterfaceInit();
void InterfaceGmouseHandleHook();
+2
View File
@@ -33,6 +33,7 @@
#include "Graphics.h"
#include "HeroAppearance.h"
#include "input.h"
#include "Interface.h"
#include "Inventory.h"
#include "LoadGameHook.h"
#include "LoadOrder.h"
@@ -282,6 +283,7 @@ static void __declspec(naked) EndLoadHook() {
static void __stdcall GameInitialization() { // OnBeforeGameInit
MusicVolInitialization();
InterfaceGmouseHandleHook();
}
static void __stdcall game_init_hook() { // OnGameInit
+2 -3
View File
@@ -115,6 +115,7 @@ static void __declspec(naked) queue_add_hack() {
__asm {
mov [edx + 8], edi; // queue.object
mov [edx], esi; // queue.time
//
test edi, edi;
jnz fix;
retn;
@@ -147,9 +148,7 @@ end:
}
void SetAutoUnjamLockTime(DWORD time) {
if (!unjamTimeState) {
BlockCall(0x4A364A); // disable auto unjam at midnight
}
if (!unjamTimeState) BlockCall(0x4A364A); // disable auto unjam at midnight
if (time > 0) {
SafeWrite8(0x4831D9, (BYTE)time);
+1 -1
View File
@@ -417,7 +417,7 @@ static void sf_create_win() {
if (opHandler.numArgs() == 6) {
flags = opHandler.arg(5).asInt();
} else {
flags = 0x4; // MoveOnTop
flags = WIN_MoveOnTop;
}
if (CreateWindowFunc(opHandler.arg(0).asString(),
+2 -2
View File
@@ -369,8 +369,8 @@ void TilesInit() {
SafeWrite8(Tiles_C0[i], 0xC0);
}
if (hrpVersionValid) { // Check HRP 4.1.8
SafeWrite8(HRPAddressOffset(0xE1C0), 0x40);
SafeWrite8(HRPAddressOffset(0xE1DA), 0x3F);
SafeWrite8(HRPAddress(0x1000E1C0), 0x40);
SafeWrite8(HRPAddress(0x1000E1DA), 0x3F);
}
dlogr(" Done", DL_INIT);
}
+5 -5
View File
@@ -84,8 +84,8 @@ static char translationIni[65];
DWORD modifiedIni;
DWORD hrpDLLBaseAddr = 0x10000000;
DWORD HRPAddressOffset(DWORD offset) {
return (hrpDLLBaseAddr + offset);
DWORD HRPAddress(DWORD addr) {
return (hrpDLLBaseAddr + (addr & 0xFFFFF));
}
int iniGetInt(const char* section, const char* setting, int defaultValue, const char* iniFile) {
@@ -698,8 +698,8 @@ static void DllMain2() {
if (GetConfigInt("Misc", "InterfaceDontMoveOnTop", 0)) {
dlog("Applying InterfaceDontMoveOnTop patch.", DL_INIT);
SafeWrite8(0x46ECE9, 0x10); // set only Exclusive flag for Player Inventory/Loot/UseOn
SafeWrite8(0x41B966, 0x10); // set only Exclusive flag for Automap
SafeWrite8(0x46ECE9, WIN_Exclusive); // Player Inventory/Loot/UseOn
SafeWrite8(0x41B966, WIN_Exclusive); // Automap
dlogr(" Done", DL_INIT);
}
@@ -928,7 +928,7 @@ defaultIni:
hrpIsEnabled = (*(DWORD*)0x4E4480 != 0x278805C7); // check if HRP is enabled
if (hrpIsEnabled) {
LoadHRPModule();
if (strncmp((const char*)HRPAddressOffset(0x39940), "4.1.8", 5) == 0) hrpVersionValid = true;
if (strncmp((const char*)HRPAddress(0x10039940), "4.1.8", 5) == 0) hrpVersionValid = true;
}
DllMain2();
+1 -1
View File
@@ -103,7 +103,7 @@ std::string Translate(const char* section, const char* setting, const char* defa
// Translates given string using Sfall translation INI file and puts the result into given buffer.
size_t Translate(const char* section, const char* setting, const char* defaultValue, char* buffer, size_t bufSize = 128);
DWORD HRPAddressOffset(DWORD offset);
DWORD HRPAddress(DWORD addr);
extern const char ddrawIniDef[];
extern DWORD modifiedIni;
+3 -3
View File
@@ -24,11 +24,11 @@
#define VERSION_MAJOR 3
#define VERSION_MINOR 8
#define VERSION_BUILD 21
#define VERSION_BUILD 22
#define VERSION_REV 0
#ifdef WIN2K
#define VERSION_STRING "3.8.21 win2k"
#define VERSION_STRING "3.8.22 win2k"
#else
#define VERSION_STRING "3.8.21"
#define VERSION_STRING "3.8.22"
#endif