Fixed a crash when using older versions of HRP

Fixed potential crash/bug when alt-tab out of game and get back.
Edited OnDeath hook code to minimize its hook points to the engine.
Minor edits to ddraw.ini.
This commit is contained in:
NovaRain
2020-03-26 14:06:46 +08:00
parent ce5c65d37f
commit ba911375a9
7 changed files with 75 additions and 63 deletions
+19 -19
View File
@@ -24,24 +24,6 @@ UseCommandLine=0
;Uncomment the option to specify a different folder path. The default path is <GameRoot>\mods\ ;Uncomment the option to specify a different folder path. The default path is <GameRoot>\mods\
;AutoSearchPath=mods ;AutoSearchPath=mods
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Sound]
;Sets the number of allowed simultaneous sound effects
;Set to 0 to leave the default unchanged (i.e. 4)
NumSoundBuffers=0
;Set to 1 to allow attaching sound files to combat float messages
AllowSoundForFloats=0
;Set to 1 to automatically search for alternative formats (mp3/wma/wav) when Fallout tries to play an acm
;Set to 2 to play alternative music files even if original acm files are not present in the music folder
;This does not effect the play_sfall_sound and stop_sfall_sound script functions
AllowDShowSound=0
;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg
;Set to 2 to overwrite all occurances of the music path
OverrideMusicDir=2
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Speed] [Speed]
;Set to 0 to disable everything in this section ;Set to 0 to disable everything in this section
@@ -70,7 +52,7 @@ AffectPlayback=0
;Set to 0 for 8 bit fullscreen ;Set to 0 for 8 bit fullscreen
;Set to 4 for DX9 fullscreen ;Set to 4 for DX9 fullscreen
;Set to 5 for DX9 windowed ;Set to 5 for DX9 windowed
;Set to 6 for DX9 fullscreen windowed ;Set to 6 for DX9 fullscreen windowed (the resolution in f2_res.ini should be set to the same aspect ratio as your desktop resolution)
;A DX9 mode is required for any graphics related script extender functions to work (i.e. fullscreen shaders) ;A DX9 mode is required for any graphics related script extender functions to work (i.e. fullscreen shaders)
;Modes 1, 2 and 3 are no longer supported ;Modes 1, 2 and 3 are no longer supported
Mode=0 Mode=0
@@ -136,6 +118,24 @@ WorldMapTravelMarkers=0
;Set to 1 to display terrain types when hovering the cursor over the player's marker on the world map ;Set to 1 to display terrain types when hovering the cursor over the player's marker on the world map
WorldMapTerrainInfo=0 WorldMapTerrainInfo=0
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Sound]
;Sets the number of allowed simultaneous sound effects
;Set to 0 to leave the default unchanged (i.e. 4)
NumSoundBuffers=0
;Set to 1 to allow attaching sound files to combat float messages
AllowSoundForFloats=0
;Set to 1 to automatically search for alternative formats (mp3/wma/wav) when Fallout tries to play an acm
;Set to 2 to play alternative music files even if original acm files are not present in the music folder
;This does not effect the play_sfall_sound and stop_sfall_sound script functions
AllowDShowSound=0
;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg
;Set to 2 to overwrite all occurances of the music path
OverrideMusicDir=2
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Input] [Input]
;Set to 1 to enable the mouse scroll wheel to scroll through the inventory, barter, and loot screens ;Set to 1 to enable the mouse scroll wheel to scroll through the inventory, barter, and loot screens
+4 -3
View File
@@ -70,8 +70,6 @@ void ResetBodyState() {
} }
static void Initialization() { static void Initialization() {
*(DWORD*)FO_VAR_gDialogMusicVol = *(DWORD*)FO_VAR_background_volume; // fix dialog music
// Restore calling original engine functions from HRP hacks (there is no difference in HRP functions) // Restore calling original engine functions from HRP hacks (there is no difference in HRP functions)
__int64 data = 0xC189565153; __int64 data = 0xC189565153;
SafeWriteBytes(0x4D78CC, (BYTE*)&data, 5); // win_get_top_win_ SafeWriteBytes(0x4D78CC, (BYTE*)&data, 5); // win_get_top_win_
@@ -3289,6 +3287,9 @@ void BugFixes::init()
BlockCall(0x4123F3); BlockCall(0x4123F3);
MakeCall(0x4123F8, action_loot_container_hack, 1); MakeCall(0x4123F8, action_loot_container_hack, 1);
// Fix the music volume when entering the dialog
SafeWrite32(0x44525D, (DWORD)FO_VAR_background_volume);
// Fix for the barter button on the dialog window not animating until after leaving the barter screen // Fix for the barter button on the dialog window not animating until after leaving the barter screen
HookCall(0x44A77C, gdialog_window_create_hook); HookCall(0x44A77C, gdialog_window_create_hook);
@@ -3297,7 +3298,7 @@ void BugFixes::init()
// Fix crash or animation glitch of the critter in combat when an explosion from explosives // Fix crash or animation glitch of the critter in combat when an explosion from explosives
// and the AI attack animation are performed simultaneously // and the AI attack animation are performed simultaneously
// Note: all events in combat will occur before the AI attack // Note: all events in combat will occur before the AI (party member) attack
HookCall(0x422E5F, combat_ai_hook); // execute all events after the end of the combat sequence HookCall(0x422E5F, combat_ai_hook); // execute all events after the end of the combat sequence
// Fix for the "Fill_W" flag in worldmap.txt not uncovering all tiles to the left edge of the world map // Fix for the "Fill_W" flag in worldmap.txt not uncovering all tiles to the left edge of the world map
+7 -4
View File
@@ -393,7 +393,7 @@ static void __declspec(naked) CombatTurnHook_End() {
__asm jmp fo::funcoffs::combat_over_; __asm jmp fo::funcoffs::combat_over_;
} }
// hack to exit from combat_add_noncoms function without crashing when you load game during NPC turn // hack to exit from combat_add_noncoms function without crashing when you load game during PM/NPC turn
static long countCombat = 0; static long countCombat = 0;
static void __declspec(naked) CombatTurnHook_AddNoncoms() { static void __declspec(naked) CombatTurnHook_AddNoncoms() {
__asm { __asm {
@@ -414,7 +414,7 @@ endCombat:
jz skip; jz skip;
mov countCombat, eax; mov countCombat, eax;
skip: skip:
mov ds:[FO_VAR_list_com], edx; mov ds:[FO_VAR_list_com], edx; // edx = 0
retn; retn;
} }
} }
@@ -589,7 +589,7 @@ void Inject_CombatDamageHook() {
0x424220, // attack_crit_failure() 0x424220, // attack_crit_failure()
0x4242FB, // attack_crit_failure() 0x4242FB, // attack_crit_failure()
}); });
MakeCall(0x423DEB, ComputeDamageHook); // compute_explosion_on_extras() - for the attacker MakeCall(0x423DEB, ComputeDamageHook); // compute_explosion_on_extras() - fix for the attacker
} }
void Inject_FindTargetHook() { void Inject_FindTargetHook() {
@@ -607,7 +607,10 @@ void Inject_AmmoCostHook() {
void Inject_CombatTurnHook() { void Inject_CombatTurnHook() {
HookCall(0x422354, CombatTurnHook_AddNoncoms); HookCall(0x422354, CombatTurnHook_AddNoncoms);
HookCalls(CombatTurnHook, { 0x422D87, 0x422E20 }); HookCalls(CombatTurnHook, { 0x422D87, 0x422E20 });
HookCall(0x422E85, CombatTurnHook_End); HookCalls(CombatTurnHook_End, {
0x422E85, // combat_
0x422196 // combat_over_from_load_
});
HookCall(0x422E4D, combat_hook_fix_load); HookCall(0x422E4D, combat_hook_fix_load);
} }
+18 -24
View File
@@ -74,7 +74,7 @@ static void __declspec(naked) CalcDeathAnim2Hook() {
__asm { __asm {
call fo::funcoffs::check_death_; // call original function call fo::funcoffs::check_death_; // call original function
HookBegin; HookBegin;
mov ebx, [esp + 60]; mov ebx, [esp + 60];
mov args[4], ebx; // attacker mov args[4], ebx; // attacker
mov args[8], esi; // target mov args[8], esi; // target
mov ebx, [esp + 12]; mov ebx, [esp + 12];
@@ -97,19 +97,24 @@ static void __declspec(naked) CalcDeathAnim2Hook() {
} }
static void __declspec(naked) OnDeathHook() { static void __declspec(naked) OnDeathHook() {
using namespace fo::Fields;
__asm { __asm {
HookBegin; push edx;
mov args[0], eax; call BeginHook;
call fo::funcoffs::critter_kill_; mov args[0], esi;
pushad;
} }
argCount = 1; argCount = 1;
RunHookScript(HOOK_ONDEATH); RunHookScript(HOOK_ONDEATH);
EndHook(); EndHook();
_asm popad; __asm {
_asm retn; pop edx;
// engine code
mov eax, [esi + protoId];
mov ebp, ebx;
retn;
}
} }
static void __declspec(naked) OnDeathHook2() { static void __declspec(naked) OnDeathHook2() {
@@ -137,30 +142,19 @@ void Inject_DeathAnim1Hook() {
void Inject_DeathAnim2Hook() { void Inject_DeathAnim2Hook() {
HookCalls(CalcDeathAnim2Hook, { HookCalls(CalcDeathAnim2Hook, {
0x410981, 0x410981, // show_damage_to_object_
0x4109A1, 0x4109A1, // show_damage_to_object_
0x4109BF 0x4109BF // show_damage_to_object_
}); });
registerHookDeathAnim2 = true; registerHookDeathAnim2 = true;
if (!registerHookDeathAnim1) { if (!registerHookDeathAnim1) {
HookCall(0x4109DE, CalcDeathAnimHook); HookCall(0x4109DE, CalcDeathAnimHook); // show_damage_to_object_
} }
} }
void Inject_OnDeathHook() { void Inject_OnDeathHook() {
HookCalls(OnDeathHook, { MakeCall(0x42DA6D, OnDeathHook); // critter_kill_
0x4130CC, HookCall(0x425161, OnDeathHook2); // damage_object_
0x4130EF,
0x413603,
0x426EF0,
0x42D1EC,
0x42D6F9,
0x457BC5,
0x457E3A,
0x457E54,
0x4C14F9
});
HookCall(0x425161, OnDeathHook2);
} }
void InitDeathHookScripts() { void InitDeathHookScripts() {
+5 -4
View File
@@ -40,12 +40,13 @@ static void __declspec(naked) CombatLoopHook() {
__asm { __asm {
push ecx; push ecx;
push edx; push edx;
push eax; //push eax;
call CombatLoopHook2; call CombatLoopHook2;
pop eax; //pop eax;
pop edx; pop edx;
pop ecx; call fo::funcoffs::get_input_;
jmp fo::funcoffs::get_input_; pop ecx; // prevent the combat turn from being skipped after pressing Alt-Tab
retn;
} }
} }
+9 -5
View File
@@ -489,13 +489,17 @@ static void __declspec(naked) gsound_set_sfx_volume_hack() {
static void SoundLostFocus() { static void SoundLostFocus() {
long isActive; long isActive;
__asm mov isActive, eax; __asm push ecx;
__asm mov isActive, eax;
if (isActive) { if (!loopingSounds.empty() || !playingSounds.empty()) {
ResumeAllSfallSound(); if (isActive) {
} else { ResumeAllSfallSound();
PauseAllSfallSound(); } else {
PauseAllSfallSound();
}
} }
__asm pop ecx;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
+13 -4
View File
@@ -16,6 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma comment(lib, "psapi.lib")
#include <psapi.h>
#include <algorithm> #include <algorithm>
#include <stdio.h> #include <stdio.h>
#include <memory> #include <memory>
@@ -152,8 +156,8 @@ size_t Translate(const char* section, const char* setting, const char* defaultVa
} }
int SetConfigInt(const char* section, const char* setting, int value) { int SetConfigInt(const char* section, const char* setting, int value) {
char* buf = new char[128]; char* buf = new char[33];
_itoa_s(value, buf, 128, 10); _itoa_s(value, buf, 33, 10);
int result = WritePrivateProfileStringA(section, setting, buf, ini); int result = WritePrivateProfileStringA(section, setting, buf, ini);
delete[] buf; delete[] buf;
return result; return result;
@@ -224,8 +228,8 @@ static void InitModules() {
dlogr("Leave InitModules", DL_MAIN); dlogr("Leave InitModules", DL_MAIN);
} }
static const DWORD loadFunc = 0x4FE1D0;
static void LoadHRPModule() { static void LoadHRPModule() {
static const DWORD loadFunc = 0x4FE1D0;
HMODULE dll; HMODULE dll;
__asm call loadFunc; // get HRP loading address __asm call loadFunc; // get HRP loading address
__asm mov dll, eax; __asm mov dll, eax;
@@ -331,7 +335,12 @@ defaultIni:
hrpIsEnabled = (*(DWORD*)0x4E4480 != 0x278805C7); // check if HRP is enabled hrpIsEnabled = (*(DWORD*)0x4E4480 != 0x278805C7); // check if HRP is enabled
if (hrpIsEnabled) { if (hrpIsEnabled) {
LoadHRPModule(); LoadHRPModule();
if (strncmp((const char*)HRPAddress(0x10039940), "4.1.8", 5) == 0) hrpVersionValid = true; MODULEINFO info;
if (GetModuleInformation(GetCurrentProcess(), (HMODULE)hrpDLLBaseAddr, &info, sizeof(info)) && info.SizeOfImage >= 0x39940 + 7) {
if (*(BYTE*)HRPAddress(0x10039940 + 7) == 0 && strncmp((const char*)HRPAddress(0x10039940), "4.1.8", 5) == 0) {
hrpVersionValid = true;
}
}
} }
InitModules(); InitModules();