Added a fix for scripted interface windows (#25)

* 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:11:33 +08:00
parent b8de20d455
commit 227a062fa6
13 changed files with 82 additions and 29 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
;sfall configuration settings
;v4.2.1
;v4.2.2
[Main]
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
+2 -6
View File
@@ -54,9 +54,7 @@ procedure combatturn_handler begin
// set perks (only work with 4.1.8+)
foreach (perkID in perksList) begin
level := has_trait(TRAIT_PERK, real_dude_obj, perkID);
if (level) then begin
critter_add_trait(critter, TRAIT_PERK, perkID, level);
end
if (level) then critter_add_trait(critter, TRAIT_PERK, perkID, level);
end
intface_redraw;
lightDist := get_object_data(critter, OBJ_DATA_LIGHT_DISTANCE);
@@ -83,9 +81,7 @@ procedure combatturn_handler begin
if (dude_obj != real_dude_obj) then begin
foreach (perkID in perksList) begin
level := has_trait(TRAIT_PERK, real_dude_obj, perkID);
if (level) then begin
critter_rm_trait(critter, TRAIT_PERK, perkID, level);
end
if (level) then critter_rm_trait(critter, TRAIT_PERK, perkID, level);
end
end
if isShowTag then begin
+1 -1
View File
@@ -739,7 +739,7 @@ namespace WinFlags {
Transparent = 0x20,
UnknownFlag40 = 0x40,
UnknownFlag80 = 0x80,
scriptWindow = 0x100,
ScriptWindow = 0x100,
itsButton = 0x10000,
};
}
+1
View File
@@ -25,6 +25,7 @@ WRAP_WATCOM_FFUNC3(FrmFrameData*, frame_ptr, FrmHeaderData*, frm, long, frame, l
WRAP_WATCOM_FFUNC3(void, intface_update_items, long, animate, long, modeLeft,long, modeRight)
WRAP_WATCOM_FFUNC3(long, item_add_force, GameObject*, critter, GameObject*, item, long, count)
WRAP_WATCOM_FFUNC7(void, make_straight_path_func, GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func)
WRAP_WATCOM_FFUNC4(long, mouse_click_in, long, x, long, y, long, x_end, long, y_end)
WRAP_WATCOM_FFUNC3(GameObject*, obj_blocking_at, GameObject*, object, long, tile, long, elevation)
WRAP_WATCOM_FFUNC3(long, object_under_mouse, long, crSwitch, long, inclDude, long, elevation)
WRAP_WATCOM_FFUNC3(long, scr_get_local_var, long, sid, long, varId, long*, value)
+7 -7
View File
@@ -697,20 +697,20 @@ struct ScriptListInfoItem {
//for holding window info
#pragma pack(1)
struct Window {
long ref;
long wID;
long flags;
RECT wRect;
long width;
long height;
long clearColour;
long unknown2;
long unknown3;
long rand1;
long rand2;
BYTE *surface; // bytes frame data ref to palette
long buttonListP;
long unknown5;//buttonptr?
long *buttonsList;
long unknown5; // buttonptr?
long unknown6;
long unknown7;
long drawFuncP;
long *menuBar;
long *drawFunc;
};
#pragma pack(1)
+6
View File
@@ -51,6 +51,7 @@
#define FO_VAR_dialogue_switch_mode 0x518718
#define FO_VAR_dialog_target 0x518848
#define FO_VAR_dialog_target_is_party 0x51884C
#define FO_VAR_display_win 0x631E4C
#define FO_VAR_displayMapList 0x41B560
#define FO_VAR_dropped_explosive 0x5190E0
#define FO_VAR_drugInfoList 0x5191CC
@@ -148,6 +149,7 @@
#define FO_VAR_name_sort_list 0x56FCB0
#define FO_VAR_num_game_global_vars 0x5186C4
#define FO_VAR_num_map_global_vars 0x519574
#define FO_VAR_num_windows 0x6ADF24
#define FO_VAR_card_old_fid1 0x5709EC
#define FO_VAR_obj_dude 0x6610B8
#define FO_VAR_obj_seen 0x662445
@@ -232,6 +234,7 @@
#define FO_VAR_trait_data 0x51DB84
#define FO_VAR_view_page 0x664520
#define FO_VAR_wd_obj 0x59E98C
#define FO_VAR_window 0x6ADE58
#define FO_VAR_wmAreaInfoList 0x51DDF8
#define FO_VAR_wmLastRndTime 0x51DEA0
#define FO_VAR_wmMaxMapNum 0x51DE10
@@ -248,10 +251,13 @@
// colors
#define FO_VAR_BlueColor 0x6A38EF
#define FO_VAR_DARK_GREY_Color 0x6A59D8
#define FO_VAR_DarkGreenColor 0x6A3A90
#define FO_VAR_DarkGreenGreyColor 0x6A3DF1
#define FO_VAR_DullPinkColor 0x6AB718
#define FO_VAR_GoodColor 0x6AB4EF
#define FO_VAR_GreenColor 0x6A3CB0
#define FO_VAR_LIGHT_GREY_Color 0x6A76BF
#define FO_VAR_PeanutButter 0x6A82F3
#define FO_VAR_RedColor 0x6AB4D0
#define FO_VAR_WhiteColor 0x6AB8CF
+5 -1
View File
@@ -34,7 +34,9 @@ VAR_(curr_font_num, DWORD)
VARA(curr_pc_stat, long, PCSTAT_max_pc_stat)
VAR_(curr_stack, DWORD)
VAR_(cursor_line, DWORD)
VAR_(DarkGreenColor, BYTE)
VAR_(DARK_GREY_Color, BYTE)
VAR_(DarkGreenColor, BYTE)
VAR_(DarkGreenGreyColor, BYTE)
VAR_(dialogue_state, DWORD)
VAR_(dialogue_switch_mode, DWORD)
VAR_(dialog_target, DWORD)
@@ -95,6 +97,7 @@ VAR_(last_button_winID, DWORD)
VAR_(last_level, DWORD)
VAR_(Level_, DWORD)
VAR_(Lifegiver, DWORD)
VAR_(LIGHT_GREY_Color, BYTE)
VAR_(lipsFID, DWORD)
VAR_(list_com, DWORD)
VAR_(list_total, DWORD)
@@ -200,6 +203,7 @@ VAR_(title_font, DWORD)
VARA(trait_data, TraitInfo, TRAIT_count)
VAR_(view_page, DWORD)
VAR_(wd_obj, DWORD)
VARA(window, fo::Window*, 50)
VAR_(WhiteColor, BYTE)
VAR_(wmAreaInfoList, DWORD)
VAR_(wmLastRndTime, DWORD)
+49 -2
View File
@@ -81,8 +81,8 @@ static void ActionPointsBarPatch() {
dlog("Applying expanded action points bar patch.", DL_INIT);
if (hrpIsEnabled) {
// check valid data
if (hrpVersionValid && !_stricmp((const char*)HRPAddressOffset(0x39358), "HR_IFACE_%i.frm")) {
SafeWriteStr(HRPAddressOffset(0x39363), "E.frm"); // patching HRP
if (hrpVersionValid && !_stricmp((const char*)HRPAddress(0x10039358), "HR_IFACE_%i.frm")) {
SafeWriteStr(HRPAddress(0x10039363), "E.frm"); // patching HRP
} else {
dlogr(" Incorrect HRP version!", DL_INIT);
return;
@@ -561,6 +561,44 @@ static void SpeedInterfaceCounterAnimsPatch() {
}
}
static bool IFACE_BAR_MODE = false;
static long gmouse_handle_event_hook() {
long countWin = *(DWORD*)FO_VAR_num_windows;
long ifaceWin = fo::var::interfaceWindow;
fo::Window* win = nullptr;
for (int n = 1; n < countWin; n++) {
win = fo::var::window[n];
if ((win->wID == ifaceWin || (win->flags & fo::WinFlags::ScriptWindow && !(win->flags & fo::WinFlags::Transparent))) // also check the script windows
&& !(win->flags & fo::WinFlags::Hidden)) {
RECT *rect = &win->wRect;
if (fo::func::mouse_click_in(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 = fo::func::GNW_find(*(DWORD*)FO_VAR_display_win);
RECT *rect = &win->wRect;
return fo::func::mouse_click_in(rect->left, rect->top, rect->right, rect->bottom); // 1 - click in the display_win area
}
static void __declspec(naked) gmouse_bk_process_hook() {
using namespace fo::WinFlags;
__asm {
call fo::funcoffs::win_get_top_win_;
cmp eax, ds:[FO_VAR_display_win];
jnz checkFlag;
retn;
checkFlag:
call fo::funcoffs::GNW_find_;
cmp [eax + 4], Hidden; // window flags
jnz skip;
mov eax, ds:[FO_VAR_display_win]; // window is hidden, so return the number of the display_win
skip:
retn;
}
}
void Interface::init() {
if (GetConfigInt("Interface", "ActionPointsBar", 0)) {
ActionPointsBarPatch();
@@ -568,6 +606,15 @@ void Interface::init() {
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);
LoadGameHook::OnBeforeGameInit() += []() {
if (hrpVersionValid) IFACE_BAR_MODE = *(BYTE*)HRPAddress(0x1006EB0C) != 0;
HookCall(0x44C018, gmouse_handle_event_hook); // replaces hack function from HRP
};
}
void Interface::exit() {
+2 -3
View File
@@ -120,6 +120,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;
@@ -152,9 +153,7 @@ end:
}
void Objects::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);
+2 -2
View File
@@ -274,8 +274,8 @@ void Tiles::init() {
SafeWriteBatch<BYTE>(0x40, Tiles_40);
SafeWriteBatch<BYTE>(0xC0, Tiles_C0);
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);
}
+3 -3
View File
@@ -98,8 +98,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) {
@@ -323,7 +323,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;
}
InitModules();
+1 -1
View File
@@ -106,7 +106,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 ddrawIni[];
extern DWORD modifiedIni;
+2 -2
View File
@@ -24,7 +24,7 @@
#define VERSION_MAJOR 4
#define VERSION_MINOR 2
#define VERSION_BUILD 1
#define VERSION_BUILD 2
#define VERSION_REV 0
#define VERSION_STRING "4.2.1"
#define VERSION_STRING "4.2.2"