Added new modes for get_game_mod to match Crafty's; implemented HookCalls function to reduce code duplication #66

This commit is contained in:
phobos2077
2017-03-26 19:41:04 +07:00
parent 945f4696d7
commit c32dc7664e
10 changed files with 127 additions and 75 deletions
+4
View File
@@ -14,6 +14,10 @@
#define INVENTORY (0x1000)
#define AUTOMAP (0x2000)
#define SKILLDEX (0x4000)
#define INTFACEUSE (0x8000)
#define INTFACELOOT (0x10000)
#define BARTER (0x20000)
#define HEROWIN (0x40000)
//Valid arguments to register_hook
#define HOOK_TOHIT (0)
+2 -2
View File
@@ -448,8 +448,8 @@ void RefreshGraphics() {
}
for (int d = shaders.size() - 1; d >= 0; d--) {
if (!shaders[d].Effect || !shaders[d].Active) continue;
if (shaders[d].mode2 && !(shaders[d].mode2&GetCurrentLoops())) continue;
if (shaders[d].mode&GetCurrentLoops()) continue;
if (shaders[d].mode2 && !(shaders[d].mode2&GetLoopFlags())) continue;
if (shaders[d].mode&GetLoopFlags()) continue;
if (shaders[d].ehTicks) shaders[d].Effect->SetInt(shaders[d].ehTicks, GetTickCount());
UINT passes;
shaders[d].Effect->Begin(&passes, 0);
+4
View File
@@ -1077,6 +1077,8 @@ void _stdcall HeroSelectWindow(int RaceStyleFlag) {
DWORD RedrawTick = 0;
SetLoopFlag(LoopFlag::HEROWIN);
while (!exitMenu) { //main loop
NewTick = GetTickCount(); //timer for redraw
if (OldTick > NewTick)
@@ -1168,6 +1170,8 @@ void _stdcall HeroSelectWindow(int RaceStyleFlag) {
}
}
ClearLoopFlag(LoopFlag::HEROWIN);
fo::func::art_flush();
LoadHeroDat(currentRaceVal, currentStyleVal);
SetAppearanceGlobals(currentRaceVal, currentStyleVal);
+1 -1
View File
@@ -43,7 +43,7 @@ fo::GameObject* GetActiveItem() {
void InventoryKeyPressedHook(DWORD dxKey, bool pressed, DWORD vKey) {
// TODO: move this out into a script
if (pressed && reloadWeaponKey && dxKey == reloadWeaponKey && IsMapLoaded() && (GetCurrentLoops() & ~(COMBAT | PCOMBAT)) == 0) {
if (pressed && reloadWeaponKey && dxKey == reloadWeaponKey && IsMapLoaded() && (GetLoopFlags() & ~(COMBAT | PCOMBAT)) == 0) {
DWORD maxAmmo, curAmmo;
fo::GameObject* item = GetActiveItem();
maxAmmo = fo::func::item_w_max_ammo(item);
+76 -54
View File
@@ -60,10 +60,18 @@ DWORD InCombat() {
return (inLoop&COMBAT) ? 1 : 0;
}
DWORD GetCurrentLoops() {
DWORD GetLoopFlags() {
return inLoop;
}
void SetLoopFlag(LoopFlag flag) {
inLoop |= flag;
}
void ClearLoopFlag(LoopFlag flag) {
inLoop &= ~flag;
}
// called whenever game is being reset (prior to loading a save or when returning to main menu)
static void _stdcall GameReset() {
onGameReset.invoke();
@@ -386,7 +394,7 @@ static void __declspec(naked) SkilldexHook() {
}
}
static void __declspec(naked) InventoryHook() {
static void __declspec(naked) HandleInventoryHook() {
__asm {
or inLoop, INVENTORY;
call fo::funcoffs::handle_inventory_;
@@ -395,11 +403,38 @@ static void __declspec(naked) InventoryHook() {
}
}
static void __declspec(naked) UseInventoryOnHook() {
__asm {
or inLoop, INTFACEUSE;
call fo::funcoffs::use_inventory_on_;
and inLoop, (-1 ^ INTFACEUSE);
retn;
}
}
static void __declspec(naked) LootContainerHook() {
__asm {
or inLoop, INTFACELOOT;
call fo::funcoffs::loot_container_;
and inLoop, (-1 ^ INTFACELOOT);
retn;
}
}
static void __declspec(naked) BarterInventoryHook() {
__asm {
or inLoop, BARTER;
call fo::funcoffs::barter_inventory_;
and inLoop, (-1 ^ BARTER);
retn;
}
}
static void __declspec(naked) AutomapHook() {
__asm {
or inLoop, AUTOMAP;
call fo::funcoffs::automap_;
and inLoop, (-1^AUTOMAP);
and inLoop, (-1 ^ AUTOMAP);
retn;
}
}
@@ -411,58 +446,45 @@ void LoadGameHook::init() {
saveSfallDataFailMsg = Translate("sfall", "SaveSfallDataFail",
"ERROR saving extended savegame information! Check if other programs interfere with savegame files/folders and try again!");
HookCall(0x4809BA, main_init_system_hook);
HookCall(0x480AAE, main_load_new_hook);
HookCall(0x47C72C, LoadSlot_hook);
HookCall(0x47D1C9, LoadSlot_hook);
HookCall(0x443AE4, LoadGame_hook);
HookCall(0x443B89, LoadGame_hook);
HookCall(0x480B77, LoadGame_hook);
HookCall(0x48FD35, LoadGame_hook);
HookCall(0x443AAC, SaveGame_hook);
HookCall(0x443B1C, SaveGame_hook);
HookCall(0x48FCFF, SaveGame_hook);
HookCall(0x47DD6B, game_reset_hook); // LoadSlot_
HookCall(0x47DDF3, game_reset_hook); // LoadSlot_
HookCall(0x47F491, game_reset_hook); // PrepLoad_
HookCall(0x480708, game_reset_hook); // RestoreLoad_ (never called)
HookCall(0x480AD3, game_reset_hook); // gnw_main_
HookCall(0x480BCC, game_reset_hook); // gnw_main_
HookCall(0x480D0C, game_reset_hook); // main_reset_system_ (never called)
HookCall(0x481028, game_reset_hook); // main_selfrun_record_
HookCall(0x481062, game_reset_hook); // main_selfrun_record_
HookCall(0x48110B, game_reset_hook); // main_selfrun_play_
HookCall(0x481145, game_reset_hook); // main_selfrun_play_
HookCalls(main_init_system_hook, {0x4809BA});
HookCalls(main_load_new_hook, {0x480AAE});
HookCalls(LoadSlot_hook, {0x47C72C, 0x47D1C9});
HookCalls(LoadGame_hook, {0x443AE4, 0x443B89, 0x480B77, 0x48FD35});
HookCalls(SaveGame_hook, {0x443AAC, 0x443B1C, 0x48FCFF});
HookCalls(game_reset_hook, {
0x47DD6B, // LoadSlot_
0x47DDF3, // LoadSlot_
0x47F491, // PrepLoad_
0x480708, // RestoreLoad_ (never called)
0x480AD3, // gnw_main_
0x480BCC, // gnw_main_
0x480D0C, // main_reset_system_ (never called)
0x481028, // main_selfrun_record_
0x481062, // main_selfrun_record_
0x48110B, // main_selfrun_play_
0x481145 // main_selfrun_play_
});
HookCall(0x483668, WorldMapHook);
HookCall(0x4A4073, WorldMapHook);
HookCall(0x4C4855, WorldMapHook2);
HookCall(0x426A29, CombatHook);
HookCall(0x4432BE, CombatHook);
HookCall(0x45F6D2, CombatHook);
HookCall(0x4A4020, CombatHook);
HookCall(0x4A403D, CombatHook);
HookCall(0x422B09, PlayerCombatHook);
HookCall(0x480C16, EscMenuHook);
HookCall(0x4433BE, EscMenuHook2);
HookCall(0x48FCE4, OptionsMenuHook);
HookCall(0x48FD17, OptionsMenuHook);
HookCall(0x48FD4D, OptionsMenuHook);
HookCall(0x48FD6A, OptionsMenuHook);
HookCall(0x48FD87, OptionsMenuHook);
HookCall(0x48FDB3, OptionsMenuHook);
HookCall(0x443A50, HelpMenuHook);
HookCall(0x443320, CharacterHook);
HookCall(0x4A73EB, CharacterHook);
HookCall(0x4A740A, CharacterHook);
HookCall(0x445748, DialogHook);
HookCall(0x443463, PipboyHook);
HookCall(0x443605, PipboyHook);
HookCall(0x4434AC, SkilldexHook);
HookCall(0x44C7BD, SkilldexHook);
HookCall(0x443357, InventoryHook);
HookCall(0x44396D, AutomapHook);
HookCall(0x479519, AutomapHook);
HookCalls(WorldMapHook, {0x483668, 0x4A4073});
HookCalls(WorldMapHook2, {0x4C4855});
HookCalls(CombatHook, {0x426A29, 0x4432BE, 0x45F6D2, 0x4A4020, 0x4A403D});
HookCalls(PlayerCombatHook, {0x422B09});
HookCalls(EscMenuHook, {0x480C16});
HookCalls(EscMenuHook2, {0x4433BE});
HookCalls(OptionsMenuHook, {0x48FCE4, 0x48FD17, 0x48FD4D, 0x48FD6A, 0x48FD87, 0x48FDB3});
HookCalls(HelpMenuHook, {0x443A50});
HookCalls(CharacterHook, {0x443320, 0x4A73EB, 0x4A740A});
HookCalls(DialogHook, {0x445748});
HookCalls(PipboyHook, {0x443463, 0x443605});
HookCalls(SkilldexHook, {0x4434AC, 0x44C7BD});
HookCalls(HandleInventoryHook, {0x443357});
HookCalls(UseInventoryOnHook, {0x44C6FB});
HookCalls(LootContainerHook, {
0x4746EC,
0x4A4369,
0x4A4565});
HookCalls(BarterInventoryHook, {0x4466C7});
HookCalls(AutomapHook, {0x44396D, 0x479519});
}
Delegate<>& LoadGameHook::OnGameInit() {
+29 -17
View File
@@ -52,24 +52,36 @@ DWORD InWorldMap();
DWORD InCombat();
#define WORLDMAP (1<<0) //0x1
#define LOCALMAP (1<<1) //0x2 No point hooking this: would always be 1 at any point at which scripts are running
#define DIALOG (1<<2) //0x4
#define ESCMENU (1<<3) //0x8
#define SAVEGAME (1<<4) //0x10
#define LOADGAME (1<<5) //0x20
#define COMBAT (1<<6) //0x40
#define OPTIONS (1<<7) //0x80
#define HELP (1<<8) //0x100
#define CHARSCREEN (1<<9) //0x200
#define PIPBOY (1<<10)//0x400
#define PCOMBAT (1<<11)//0x800
#define INVENTORY (1<<12)//0x1000
#define AUTOMAP (1<<13)//0x2000
#define SKILLDEX (1<<14)//0x4000
#define RESERVED (1<<31)
enum LoopFlag : unsigned long {
WORLDMAP = 1 << 0, // 0x1
LOCALMAP = 1 << 1, // 0x2 No point hooking this: would always be 1 at any point at which scripts are running
DIALOG = 1 << 2, // 0x4
ESCMENU = 1 << 3, // 0x8
SAVEGAME = 1 << 4, // 0x10
LOADGAME = 1 << 5, // 0x20
COMBAT = 1 << 6, // 0x40
OPTIONS = 1 << 7, // 0x80
HELP = 1 << 8, // 0x100
CHARSCREEN = 1 << 9, // 0x200
PIPBOY = 1 << 10, // 0x400
PCOMBAT = 1 << 11, // 0x800
INVENTORY = 1 << 12, // 0x1000
AUTOMAP = 1 << 13, // 0x2000
SKILLDEX = 1 << 14, // 0x4000
INTFACEUSE = 1 << 15, // 0x8000
INTFACELOOT = 1 << 16, // 0x10000
BARTER = 1 << 17, // 0x20000
HEROWIN = 1 << 18, // 0x40000
// RESERVED = 1 << 31
};
DWORD GetCurrentLoops();
DWORD GetLoopFlags();
// set the given flag
void SetLoopFlag(LoopFlag flag);
// unset the given flag
void ClearLoopFlag(LoopFlag flag);
void GetSavePath(char* buf, char* ftype);
@@ -142,7 +142,7 @@ void __declspec(naked) op_get_game_mode() {
__asm {
pushad;
mov edi, eax;
call GetCurrentLoops;
call GetLoopFlags;
mov edx, eax;
mov eax, edi;
call fo::funcoffs::interpretPushLong_;
+6
View File
@@ -54,6 +54,12 @@ void MakeCall(DWORD addr, void* func, bool jump) {
HookCall(addr, func);
}
void HookCalls(void* func, std::initializer_list<DWORD> addrs) {
for (auto addr : addrs) {
HookCall(addr, func);
}
}
void SafeMemSet(DWORD addr, BYTE val, int len) {
DWORD oldProtect;
+3
View File
@@ -1,5 +1,6 @@
#pragma once
#include <initializer_list>
#include <Windows.h>
namespace sfall
@@ -21,4 +22,6 @@ void BlockCall(DWORD addr);
void SafeMemSet(DWORD addr, BYTE val, int len);
void SafeWriteBytes(DWORD addr, BYTE* data, int count);
void HookCalls(void* func, std::initializer_list<DWORD> addrs);
}
+1
View File
@@ -2,6 +2,7 @@
#include <algorithm>
#include <functional>
#include <initializer_list>
#include <memory>
#include <vector>
#include <unordered_map>