Added missing functions (was causing errors)

Added an improvement to prevent the player from running outside the
cropped part of the map.

Added an improvement for the list of action icons when enabling
IFACE_BAR_MODE (the list is no longer created under the interface).
This commit is contained in:
NovaRain
2021-12-16 12:28:26 +08:00
parent fb8ca5317f
commit 3145d4e5dc
12 changed files with 216 additions and 56 deletions
+1 -1
View File
@@ -29,6 +29,7 @@ WRAP_WATCOM_FFUNC3(void, check_for_death, fo::GameObject*, critter, long, amount
WRAP_WATCOM_FFUNC6(long, combat_safety_invalidate_weapon_func, fo::GameObject*, source, fo::GameObject*, weapon, long, hitMode, fo::GameObject*, targetA, DWORD*, outSafeRange, fo::GameObject*, targetB)
WRAP_WATCOM_FFUNC3(void, correctFidForRemovedItem, fo::GameObject*, critter, fo::GameObject*, item, long, slotFlag)
WRAP_WATCOM_FFUNC7(long, createWindow, const char*, winName, DWORD, x, DWORD, y, DWORD, width, DWORD, height, long, color, long, flags)
WRAP_WATCOM_FFUNC8(void, cscale, BYTE*, src, long, sWidth, long, sHeight, long, sStride, BYTE*, dst, long, width, long, height, long, stride)
WRAP_WATCOM_FFUNC4(long, determine_to_hit, fo::GameObject*, source, fo::GameObject*, target, long, bodyPart, long, hitMode)
WRAP_WATCOM_FFUNC3(void, display_inventory, long, inventoryOffset, long, visibleOffset, long, mode)
WRAP_WATCOM_FFUNC4(void, display_target_inventory, long, inventoryOffset, long, visibleOffset, DWORD*, targetInventory, long, mode)
@@ -73,7 +74,6 @@ WRAP_WATCOM_FFUNC4(void, wmInterfaceDrawSubTileRectFogged, BYTE*, surface, long,
WRAP_WATCOM_FFUNC3(const char*, interpretGetString, fo::Program*, scriptPtr, DWORD, dataType, DWORD, strId)
//WRAP_WATCOM_FFUNC6(void, drawScaledBuf, BYTE*, dst, long, dstW, long, dstH, const BYTE*, src, long, w, long, h)
WRAP_WATCOM_FFUNC8(void, cscale, BYTE*, src, long, sWidth, long, sHeight, long, sStride, BYTE*, dst, long, width, long, height, long, stride)
/* stdcall */
WRAP_WATCOM_FUNC1(fo::AIcap*, ai_cap, fo::GameObject*, critter)
+1
View File
@@ -328,6 +328,7 @@
#define FO_VAR_text_width 0x51E3C0
#define FO_VAR_tile 0x631D30
#define FO_VAR_tile_center_tile 0x66BE34
#define FO_VAR_tile_mask 0x66B9C4
#define FO_VAR_tile_offx 0x66BDFC
#define FO_VAR_tile_offy 0x66BDF8
#define FO_VAR_tile_x 0x66BE18
+3 -1
View File
@@ -21,7 +21,7 @@ VAR_(btncnt, DWORD)
VARD(cap, fo::AIcap) // dynamic array
VAR_(carCurrentArea, DWORD)
VAR_(carGasAmount, long) // from 0 to 80000
VAR_(cmap, DWORD)
VARA(cmap, fo::PALETTE, 256)
VAR_(colorTable, DWORD)
VAR_(combat_end_due_to_load, DWORD)
VAR_(combat_free_move, DWORD)
@@ -143,6 +143,7 @@ VAR_(mouse_y_, DWORD)
VAR_(movePointRect, fo::BoundRect)
VARA(movie_list, const char*, 17)
VAR_(Mutate_, DWORD)
//VAR_(mve_win_rect, fo::BoundRect)
VAR_(name_color, DWORD)
VAR_(name_font, DWORD)
VAR_(name_sort_list, DWORD)
@@ -235,6 +236,7 @@ VAR_(text_spacing, DWORD)
VAR_(text_to_buf, DWORD)
VAR_(text_width, DWORD)
VAR_(tile, DWORD)
VARA(tile_mask, BYTE, 512)
VAR_(title_color, DWORD)
VAR_(title_font, DWORD)
VARA(trait_data, fo::TraitInfo, fo::TRAIT_count)
+9 -16
View File
@@ -229,7 +229,7 @@ void Setting::init(const char* exeFileName, std::string &cmdline) {
if (Setting::ExternalEnabled()) {
char infoMsg[512];
sf::Translate::Get("sfall", "HiResInfo",
"This version of sfall has its own integrated High Resolution mode patch, which is compatible with the High Resolution Patch by Mash.\n\n"
"This version of sfall has its own integrated High Resolution mode patch, which is compatible with the settings of the High Resolution Patch by Mash.\n\n"
"If you want to continue using the High Resolution Patch by Mash without seeing this message, disable the 'HiResMode' option in the ddraw.ini file.\n"
"Or you can disable the external HRP to get new graphic improvements from sfall.\n\n"
"Do you want to disable the High Resolution Patch by Mash?", infoMsg, 512);
@@ -256,18 +256,6 @@ void Setting::init(const char* exeFileName, std::string &cmdline) {
// Read High Resolution config
/*
if (IniReader::GetInt("Main", "SCALE_2X", 0, f2ResIni)) {
SCR_WIDTH /= 2;
SCR_HEIGHT /= 2;
if (SCR_WIDTH < 640) SCR_WIDTH = 640;
if (SCR_HEIGHT < 480) SCR_HEIGHT = 480;
SCALE_2X = true;
};
*/
int windowed = (sf::IniReader::GetInt("Main", "WINDOWED", 0, f2ResIni) != 0) ? 1 : 0;
if (windowed && sf::IniReader::GetInt("Main", "WINDOWED_FULLSCREEN", 0, f2ResIni)) {
windowed += 1;
@@ -285,9 +273,14 @@ void Setting::init(const char* exeFileName, std::string &cmdline) {
if (COLOUR_BITS != 32 && COLOUR_BITS != 24 && COLOUR_BITS != 16) COLOUR_BITS = 32;
}
if (SCR_HEIGHT >= 960 && SCR_WIDTH >= 1280 && sf::IniReader::GetInt("Main", "SCALE_2X", 0, f2ResIni)) {
SCR_WIDTH /= 2;
SCR_HEIGHT /= 2;
if (sf::IniReader::GetInt("Main", "SCALE_2X", 0, f2ResIni)) {
if (SCR_HEIGHT < 960 && SCR_WIDTH < 1280) {
SCR_WIDTH = 640;
SCR_HEIGHT = 480;
} else {
SCR_WIDTH /= 2;
SCR_HEIGHT /= 2;
}
SCALE_2X = 1;
}
+5 -5
View File
@@ -565,13 +565,13 @@ void IFaceBar::init() {
if (IFACE_BAR_MODE > 0) {
// Set view map height to game resolution
// replace subtract 99 with add 1
sf::SafeWrite8(0x481CDF, 1);
sf::SafeWrite8(0x481E2E, 1);
sf::SafeWrite8(0x481CDF, 1); // iso_init_
sf::SafeWrite8(0x481E2E, 1); // iso_init_
// replace subtract 99 with add 1
sf::SafeWrite8(0x481DC3, -1);
sf::SafeWrite8(0x4827A9, -1);
sf::SafeWrite8(0x481DC3, -1); // iso_init_
sf::SafeWrite8(0x4827A9, -1); // map_scroll_
// remove subtract 100
sf::SafeWrite8(0x48284F, 0);
sf::SafeWrite8(0x48284F, 0); // map_scroll_
}
sf::LoadGameHook::OnBeforeGameClose() += []() {
+6 -7
View File
@@ -17,12 +17,11 @@ namespace HRP
namespace sf = sfall;
static EdgeBorder::Edge* MapEdgeData;
static EdgeBorder::Edge* MapEdgeData = nullptr;
static EdgeBorder::Edge* currentMapEdge; // reference
static long edgeVersion; // 0 - version 1 (obsolete), 1 - version 2 (current)
static bool isDefaultSetEdge;
//bool isLoadingMapEdge;
static bool isSetDefaultEdge;
long EdgeBorder::EdgeVersion() { return edgeVersion; }
@@ -120,7 +119,7 @@ static void SetDefaultEdgeData() {
edge->nextEdgeData = nullptr;
}
edgeVersion = 0;
isDefaultSetEdge = true;
isSetDefaultEdge = true;
}
// Implementation from HRP by Mash
@@ -212,8 +211,6 @@ static fo::DbFile* LoadMapEdgeFileSub(char* mapName) {
}
static void __fastcall LoadMapEdgeFile() {
//isLoadingMapEdge = 0;
fo::DbFile* file = LoadMapEdgeFileSub(sf::LoadGameHook::mapLoadingName);
if (file) { // load error
fo::func::db_fclose(file);
@@ -223,7 +220,7 @@ static void __fastcall LoadMapEdgeFile() {
// Implementation from HRP by Mash
long EdgeBorder::GetCenterTile(long tile, long mapLevel) {
if (!isDefaultSetEdge) SetDefaultEdgeData(); // needed at game initialization
if (!isSetDefaultEdge) SetDefaultEdgeData(); // needed at game initialization
long tX, tY;
ViewMap::GetTileCoordOffset(tile, tX, tY);
@@ -333,6 +330,8 @@ long EdgeBorder::CheckBorder(long tile) {
void EdgeBorder::init() {
sf::LoadGameHook::OnBeforeMapLoad() += LoadMapEdgeFile;
sf::LoadGameHook::OnBeforeGameClose() += []() { delete[] MapEdgeData; };
}
}
-1
View File
@@ -31,7 +31,6 @@ public:
};
}
private:
~Edge() {
Release();
}
+58 -1
View File
@@ -7,6 +7,7 @@
#include "..\..\main.h"
#include "..\..\FalloutEngine\Fallout2.h"
#include "..\InterfaceBar.h"
#include "EdgeBorder.h"
#include "ViewMap.h"
@@ -218,13 +219,69 @@ static void __declspec(naked) obj_render_post_roof_hook_rect_inside_bound() {
}
}
static long rightLimit = -1;
static long __fastcall gmouse_scr_offy_map_limit() {
rightLimit = -1;
long bottom = fo::var::scr_size.offy;
if (bottom > mapVisibleArea.bottom) {
return mapVisibleArea.bottom + 1 + 99; // +99 takes into account the subtraction in the engine
}
if (IFaceBar::IFACE_BAR_MODE) {
long x, y;
fo::func::mouse_get_position(&x, &y);
fo::Window* win = fo::func::GNW_find(fo::var::interfaceWindow);
if ((x + 25) > win->rect.offx || (x + 68) < win->rect.x) {
bottom += 100; // does not enter the interface area
} else if ((x + 25) < win->rect.x) {
bottom += 100;
rightLimit = win->rect.x;
}
}
return bottom;
}
static void __declspec(naked) gmouse_scr_offx_map_limit() {
__asm {
mov eax, ds:[FO_VAR_scr_size + 8]; // scr_size.offx
cmp eax, mapVisibleArea.right;
jle skip;
mov eax, mapVisibleArea.right;
//inc eax;
retn;
skip:
cmp rightLimit, eax;
cmovb eax, rightLimit;
retn;
}
}
long EdgeClipping::CheckMapClipping() {
if (!ViewMap::EDGE_CLIPPING_ON) return 1;
return fo::func::mouse_click_in(mapVisibleArea.left, mapVisibleArea.top, mapVisibleArea.right, mapVisibleArea.bottom);
}
void EdgeClipping::init() {
sf::HookCall(0x4B15F6, refresh_game_hook_rect_inside_bound);
sf::HookCall(0x483EF0, map_scroll_refresh_game_hook_rect_inside_bound);
sf::MakeCall(0x44E481, gmouse_check_scrolling_hack); // from HRP 3.06 (TODO: redo the implementation so that the scrolling of the map works)
// Prevents rendering of "post roof" objects (fixes the red pixels from the hex cursor remaining at the edges of the cropped part of the map)
// Prevents the rendering of "post roof" objects (fixes the red pixels from the hex cursor remaining at the edges of the cropped part of the map)
sf::HookCall(0x489802, obj_render_post_roof_hook_rect_inside_bound);
// Limits the creation of the list of action icons beyond the visible map area or the bottom panel of the interface bar
// (this should be removed after changing the implementation of the list of action icons)
// gmouse_handle_event_
sf::MakeCall(0x44C597, gmouse_scr_offy_map_limit);
sf::MakeCall(0x44C5AC, gmouse_scr_offx_map_limit);
// the same thing, only when hovering the cursor over objects
// gmouse_bk_process_
sf::MakeCall(0x44BA40, gmouse_scr_offy_map_limit);
sf::MakeCall(0x44BA55, gmouse_scr_offx_map_limit);
}
}
+2
View File
@@ -13,6 +13,8 @@ class EdgeClipping {
public:
static void init();
static long CheckMapClipping();
};
}
+108 -14
View File
@@ -78,9 +78,7 @@ void ViewMap::GetWinMapHalfSize(long &outW, long &outH) {
static long __fastcall tile_set_center(long tile, long modeFlags) {
if (tile < 0 || tile >= 40000) return -1; // _grid_size: 40000
long mapElevation = fo::var::map_elevation;
if (modeFlags) tile = EdgeBorder::GetCenterTile(tile, mapElevation);
if (modeFlags) tile = EdgeBorder::GetCenterTile(tile, fo::var::map_elevation); // get the center tile in what cases?
if (!(modeFlags & 2) && fo::var::getInt(FO_VAR_scroll_limiting_on)) {
long x, y;
@@ -144,7 +142,7 @@ static long __fastcall tile_set_center(long tile, long modeFlags) {
if (modeFlags & 1 && fo::var::getInt(FO_VAR_refresh_enabled)) {
fo::func::tile_refresh_display();
return -1; // this fixes a map rendering bug, but why?
return -1; // necessary for the correct rendering of the map
}
return 0;
}
@@ -321,21 +319,114 @@ static void __declspec(naked) obj_render_pre_roof_hack_1() {
static void __declspec(naked) obj_render_pre_roof_hack() {
__asm {
mov ebx, [eax];
lea eax, [edx + ebx];
cmp eax, 40000; // _grid_size
jge capMax;
cmp eax, 0;
jl capMin;
lea eax, [edx + ebx]; // edx - tilenum
cmp eax, 40000; // _grid_size
jge tileMax;
test eax, eax;
js tileMin;
retn;
capMax:
tileMax:
mov eax, 39999;
retn;
capMin:
tileMin:
xor eax, eax;
retn;
}
}
static void __declspec(naked) obj_create_intersect_list_hack() {
__asm {
mov ecx, [ebx + eax];
lea eax, [edx + ecx]; // edx - tilenum
cmp eax, 40000; // _grid_size
jge tileMax;
test eax, eax;
js tileMin;
retn;
tileMax:
mov eax, 39999;
retn;
tileMin:
xor eax, eax;
retn;
}
}
// Implementation of tile_num_ engine function without checking the grid boundary (from HRP 3.0.6 by Mash)
static long __fastcall tile_num_HRP(long x, long y) {
long X, Y;
long yTileOff = y - fo::var::getInt(FO_VAR_tile_offy);
if (yTileOff >= 0) {
Y = yTileOff / 12;
} else {
Y = (yTileOff + 1) / 12 - 1;
}
long xTileOff = x - fo::var::getInt(FO_VAR_tile_offx) - 16 * Y;
if (xTileOff >= 0) {
X = xTileOff / 64;
} else {
//__asm {
// mov eax, xTileOff;
// inc eax;
// mov edx, eax;
// sar edx, 31; // always -1
// shl edx, 6; // always -64
// sbb eax, edx;
// sar eax, 6;
// dec eax;
// mov X, eax;
//}
X = ((xTileOff + 1) / 64) - 1;
}
long xOffset = xTileOff - (X * 64);
long yOffset = yTileOff - 12 * Y;
long tY = X + Y;
long tX = X * 2;
if (xOffset >= 32) {
xOffset -= 32;
tX++;
}
long xTile = fo::var::getInt(FO_VAR_tile_x) + tX;
long yTile = fo::var::getInt(FO_VAR_tile_y) + tY;
switch (fo::var::tile_mask[(32 * yOffset) + xOffset]) {
case 1:
yTile--;
break;
case 2:
if (++xTile & 1) yTile--;
break;
case 3:
if (!(--xTile & 1)) yTile++;
break;
case 4:
yTile++;
break;
}
return (grid_width * yTile) + (grid_width - 1 - xTile);
}
static void __declspec(naked) obj_render_pre_roof_hack_tile_num() {
__asm {
push ecx;
call tile_num_HRP;
pop ecx;
retn;
}
}
static void __declspec(naked) obj_create_intersect_list_hack_tile_num() {
__asm {
mov ecx, eax;
jmp tile_num_HRP;
}
}
void ViewMap::init() {
if (SCROLL_DIST_X <= 0) SCROLL_DIST_X = 480;
else if (SCROLL_DIST_X < 320) SCROLL_DIST_X = 320;
@@ -352,11 +443,14 @@ void ViewMap::init() {
sf::MakeCall(0x489730, obj_render_pre_roof_hack_0, 1);
sf::MakeCall(0x4897E3, obj_render_pre_roof_hack_1);
// Fix
sf::MakeCall(0x489665, obj_render_pre_roof_hack); // find the bug
// Fixes from 3.06 (fix crashes when going beyond the limits of the vanilla grid size of the map)
sf::MakeCall(0x489665, obj_render_pre_roof_hack);
sf::HookCall(0x4895B7, obj_render_pre_roof_hack_tile_num); // replace the tile_num_ function
sf::MakeCall(0x48C66B, obj_create_intersect_list_hack, 1);
sf::HookCall(0x48C5F3, obj_create_intersect_list_hack_tile_num); // replace the tile_num_ function
obj_on_screen_rect.width = Setting::ScreenWidth();
obj_on_screen_rect.height = Setting::ScreenHeight(); // maybe take into account the interface bar and be: height - 100?
obj_on_screen_rect.height = Setting::ScreenHeight(); // (maybe it should take into account the interface bar)
sf::SafeWrite32(0x45C886, (DWORD)&obj_on_screen_rect); // replace rectangle in op_obj_on_screen_
EdgeBorder::init();
+19 -4
View File
@@ -27,6 +27,7 @@
#include "Worldmap.h"
#include "..\HRP\InterfaceBar.h"
#include "..\HRP\viewmap\EdgeClipping.h"
#include "Interface.h"
@@ -932,6 +933,9 @@ static void SpeedInterfaceCounterAnimsPatch() {
static bool IFACE_BAR_MODE = false;
static long gmouse_handle_event_hook() {
// check whether the player clicks on the clipping area of the map
if (!HRP::EdgeClipping::CheckMapClipping()) return 0; // block
long countWin = fo::var::num_windows;
long ifaceWin = fo::var::interfaceWindow;
fo::Window* win = nullptr;
@@ -944,7 +948,9 @@ static long gmouse_handle_event_hook() {
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(fo::var::getInt(FO_VAR_display_win));
RECT *rect = &win->wRect;
@@ -1035,6 +1041,10 @@ static void UIAnimationSpeedPatch() {
SimplePatch<BYTE>(&addrs[4], 2, "Misc", "PipboyTimeAnimDelay", 50, 0, 127);
}
static void HackMouseEvent() {
HookCall(0x44C018, gmouse_handle_event_hook);
}
void Interface::init() {
InterfaceWindowPatch();
InventoryCharacterRotationSpeedPatch();
@@ -1055,10 +1065,15 @@ void Interface::init() {
// 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);
LoadGameHook::OnBeforeGameInit() += []() {
if (HRP::Setting::VersionIsValid) IFACE_BAR_MODE = (GetIntHRPValue(HRP_VAR_IFACE_BAR_MODE) != 0);
HookCall(0x44C018, gmouse_handle_event_hook); // replaces hack function from HRP
};
if (HRP::Setting::IsEnabled()) {
IFACE_BAR_MODE = (HRP::IFaceBar::IFACE_BAR_MODE != 0);
HackMouseEvent();
} else {
LoadGameHook::OnBeforeGameInit() += []() {
if (HRP::Setting::VersionIsValid) IFACE_BAR_MODE = (GetIntHRPValue(HRP_VAR_IFACE_BAR_MODE) != 0);
HackMouseEvent(); // replaces hack function from HRP by Mash
};
}
}
void Interface::exit() {
+4 -6
View File
@@ -70,12 +70,12 @@ static int __stdcall WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
break;
case WM_PAINT:
if (GetUpdateRect(hWnd, &rect, 0) != 0) {
if (window && GetUpdateRect(hWnd, &rect, 0) != 0) { // it's unclear under what conditions the redrawing is required
rect.right -= 1;
rect.bottom -= 1;
__asm {
//lea eax, rect;
//call fo::funcoffs::win_refresh_all_;
lea eax, rect;
call fo::funcoffs::win_refresh_all_;
}
}
break;
@@ -221,9 +221,7 @@ void WinProc::SetMoveKeys() {
}
void WinProc::Moving() {
if ((moveWindowKey[0] != 0 && KeyDown(moveWindowKey[0])) ||
(moveWindowKey[1] != 0 && KeyDown(moveWindowKey[1])))
{
if (moveWindowKey[0] != 0 && (KeyDown(moveWindowKey[0]) || (moveWindowKey[1] != 0 && KeyDown(moveWindowKey[1])))) {
int mx, my;
GetMouse(&mx, &my);
win.x += mx;