Added a fix to prevent the player from leaving the map during death anim

* when the death animation causes the player to cross an exit grid.

Fixed the height of the black background for the subtitles on death
screens when using the hi-res patch.

Added MakeJumps method to SafeWrite.cpp and devlog_f to Logging.cpp.
This commit is contained in:
NovaRain
2020-08-17 15:07:41 +08:00
parent cbccc7de4e
commit c657a9ef86
10 changed files with 103 additions and 34 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ namespace fo
namespace func
{
// Prints debug message to debug.log file for develop build
// Prints debug message to game debug.log file for develop build
#ifndef NDEBUG
void __declspec(naked) dev_printf(const char* fmt, ...) {
__asm jmp fo::funcoffs::debug_printf_;
+1 -1
View File
@@ -29,8 +29,8 @@ namespace fo
namespace func
{
// Prints debug message to debug.log file for develop build
#ifndef NDEBUG
// Prints debug message to game debug.log file for develop build
void dev_printf(const char* fmt, ...);
#else
void dev_printf(...);
+19 -2
View File
@@ -23,7 +23,7 @@
#include <fstream>
namespace sfall
namespace sfall
{
static int DebugTypes = 0;
@@ -43,7 +43,7 @@ void dlogr(const std::string& a, int type) {
}
}
void dlog_f(const char *fmt, int type, ...) {
void dlog_f(const char* fmt, int type, ...) {
if (isDebug && (type == DL_MAIN || (type & DebugTypes))) {
va_list args;
va_start(args, type);
@@ -55,6 +55,23 @@ void dlog_f(const char *fmt, int type, ...) {
}
}
// Prints debug message to sfall log file for develop build
#ifndef NDEBUG
void devlog_f(const char* fmt, int type, ...) {
if (type == DL_MAIN || (type & DebugTypes)) {
va_list args;
va_start(args, type);
char buf[1024];
vsnprintf_s(buf, sizeof(buf), _TRUNCATE, fmt, args);
Log << buf;
Log.flush();
va_end(args);
}
}
#else
void devlog_f(...) {}
#endif
void LoggingInit() {
Log.open("sfall-log.txt", std::ios_base::out | std::ios_base::trunc);
if (iniGetInt("Debugging", "Init", 0, ::sfall::ddrawIni)) {
+10 -2
View File
@@ -26,12 +26,20 @@
#include <stdio.h>
#include <string>
namespace sfall
namespace sfall
{
void dlog(const std::string&, int type);
void dlogr(const std::string&, int type);
void dlog_f(const char *format, int type, ...);
void dlog_f(const char* fmt, int type, ...);
#ifndef NDEBUG
// Prints debug message to sfall log file for develop build
void devlog_f(const char* fmt, int type, ...);
#else
void devlog_f(...);
#endif
void LoggingInit();
}
+35
View File
@@ -2777,6 +2777,35 @@ skip:
}
}
static bool dudeIsAnimDeath = false;
static void __declspec(naked) show_damage_to_object_hack() {
static const DWORD show_damage_to_object_Ret = 0x410B90;
__asm {
jnz isDeath;
add esp, 4;
jmp show_damage_to_object_Ret;
isDeath:
cmp esi, ds:[FO_VAR_obj_dude];
sete dudeIsAnimDeath;
retn;
}
}
static void __declspec(naked) obj_move_to_tile_hack_ondeath() {
static const DWORD obj_move_to_tile_Ret = 0x48A759;
__asm {
test esi, esi;
jz skip;
cmp dudeIsAnimDeath, 0;
jnz skip;
retn;
skip:
add esp, 4;
jmp obj_move_to_tile_Ret;
}
}
void BugFixes::init()
{
#ifndef NDEBUG
@@ -2786,6 +2815,7 @@ void BugFixes::init()
// Missing game initialization
LoadGameHook::OnBeforeGameInit() += Initialization;
LoadGameHook::OnGameReset() += []() { dudeIsAnimDeath = false; };
// Fix vanilla negate operator for float values
MakeCall(0x46AB68, NegateFixHack);
@@ -3503,6 +3533,11 @@ void BugFixes::init()
// Fix to prevent the execution of critter_p_proc and game events when playing movies (same as when the dialog is active)
HookCall(0x4A3C89, doBkProcesses_hook);
// Fix to prevent the player from leaving the map when the death animation causes the player to cross an exit grid
// (e.g. fire dance or knockback animation)
MakeCall(0x41094B, show_damage_to_object_hack, 1);
MakeCall(0x48A6CB, obj_move_to_tile_hack_ondeath, 1);
}
}
+19 -25
View File
@@ -92,16 +92,14 @@ void __stdcall BeginHook() {
memcpy(&savedArgs[cDepth].oldArgs, args, argCount * sizeof(DWORD)); // values of the arguments
if (cRet) memcpy(&savedArgs[cDepth].oldRets, rets, cRet * sizeof(DWORD)); // return values
// for debugging
/*dlog_f("\nSaved cArgs/cRets: %d / %d(%d)\n", DL_HOOK, savedArgs[cDepth].argCount, savedArgs[cDepth].cRet, cRetTmp);
for (unsigned int i = 0; i < maxArgs; i++) {
dlog_f("Saved Args/Rets: %d / %d\n", DL_HOOK, savedArgs[cDepth].oldArgs[i], ((i < maxRets) ? savedArgs[cDepth].oldRets[i] : -1));
}*/
//devlog_f("\nSaved cArgs/cRet: %d / %d(%d)\n", DL_HOOK, savedArgs[cDepth].argCount, savedArgs[cDepth].cRet, cRetTmp);
//for (unsigned int i = 0; i < maxArgs; i++) {
// devlog_f("Saved Args/Rets: %d / %d\n", DL_HOOK, savedArgs[cDepth].oldArgs[i], ((i < maxRets) ? savedArgs[cDepth].oldRets[i] : -1));
//}
}
callDepth++;
#ifndef NDEBUG
dlog_f("Begin running hook, current depth: %d, current executable hook: %d\n", DL_HOOK, callDepth, currentRunHook);
#endif
devlog_f("Begin running hook, current depth: %d, current executable hook: %d\n", DL_HOOK, callDepth, currentRunHook);
}
static void __stdcall RunSpecificHookScript(HookScript *hook) {
@@ -130,25 +128,22 @@ void __stdcall RunHookScript(DWORD hook) {
for (int i = hooksCount - 1; i >= 0; i--) {
RunSpecificHookScript(&hooks[hook][i]);
// for debugging
/*dlog_f("> Hook: %d, script entry: %d done\n", DL_HOOK, hook, i);
dlog_f("> Check cArg/cRet: %d / %d(%d)\n", DL_HOOK, cArg, cRet, cRetTmp);
for (unsigned int i = 0; i < maxArgs; i++) {
dlog_f("> Check Args/Rets: %d / %d\n", DL_HOOK, args[i], ((i < maxRets) ? rets[i] : -1));
}*/
//devlog_f("> Hook: %d, script entry: %d done\n", DL_HOOK, hook, i);
//devlog_f("> Check cArg/cRet: %d / %d(%d)\n", DL_HOOK, cArg, cRet, cRetTmp);
//for (unsigned int i = 0; i < maxArgs; i++) {
// devlog_f("> Check Args/Rets: %d / %d\n", DL_HOOK, args[i], ((i < maxRets) ? rets[i] : -1));
//}
}
} else {
cArg = 0;
#ifndef NDEBUG
dlog_f(">>> Try running hook ID: %d\n", DL_HOOK, hook);
#endif
devlog_f(">>> Try running hook ID: %d\n", DL_HOOK, hook);
}
}
void __stdcall EndHook() {
#ifndef NDEBUG
dlog_f("End running hook %d, current depth: %d\n", DL_HOOK, currentRunHook, callDepth);
#endif
devlog_f("End running hook %d, current depth: %d\n", DL_HOOK, currentRunHook, callDepth);
callDepth--;
if (callDepth) {
if (callDepth <= maxDepth) {
@@ -162,11 +157,10 @@ void __stdcall EndHook() {
memcpy(args, &savedArgs[cDepth].oldArgs, argCount * sizeof(DWORD));
if (cRet) memcpy(rets, &savedArgs[cDepth].oldRets, cRet * sizeof(DWORD));
// for debugging
/*dlog_f("Restored cArgs/cRets: %d / %d(%d)\n", DL_HOOK, argCount, cRet, cRetTmp);
for (unsigned int i = 0; i < maxArgs; i++) {
dlog_f("Restored Args/Rets: %d / %d\n", args[i], ((i < maxRets) ? rets[i] : -1));
}*/
//devlog_f("Restored cArgs/cRet: %d / %d(%d)\n", DL_HOOK, argCount, cRet, cRetTmp);
//for (unsigned int i = 0; i < maxArgs; i++) {
// devlog_f("Restored Args/Rets: %d / %d\n", DL_HOOK, args[i], ((i < maxRets) ? rets[i] : -1));
//}
}
} else {
currentRunHook = -1;
+6
View File
@@ -804,6 +804,12 @@ void MiscPatches::init() {
HookCall(0x48A954, obj_move_to_tile_hook);
HookCall(0x483726, map_check_state_hook);
// Corrects the height of the black background for the subtitles on death screens
if (hrpVersionValid) {
SafeWrite8(HRPAddress(0x10011738), 10);
SafeWrite8(0x481345, 4); // main_death_scene_
}
F1EngineBehaviorPatch();
DialogueFix();
AdditionalWeaponAnimsPatch();
+5 -3
View File
@@ -478,7 +478,7 @@ bool IsGameScript(const char* filename) {
static void LoadGlobalScriptsList() {
ScriptProgram prog;
for (auto& item : globalScriptFilesList) {
auto scriptFile = item.second;
auto &scriptFile = item.second;
dlog("> " + scriptFile, DL_SCRIPT);
isGlobalScriptLoading = 1;
LoadScriptProgram(prog, scriptFile.c_str(), true);
@@ -521,7 +521,7 @@ static void PrepareGlobalScriptsListByMask() {
fo::func::debug_printf("\n[SFALL] Script: %s will not be executed. A script with the same name already exists in another directory.", fullPath);
continue;
}
globalScriptFilesList.insert(std::make_pair(baseName, fullPath));
globalScriptFilesList.insert(std::make_pair(baseName, fullPath)); // script files should be sorted in alphabetical order
}
}
fo::func::db_free_file_list(&filenames, 0);
@@ -662,10 +662,12 @@ static DWORD HandleTimedEventScripts() {
executeTimedEventDepth++;
fo::func::dev_printf("\n[TimedEventScripts] Time: %d / Depth: %d", currentTime, executeTimedEventDepth);
for (auto it = timerEventScripts.cbegin(); it != timerEventScripts.cend(); ++it) {
fo::func::dev_printf("\n[TimedEventScripts] Event: %d", it->time);
}
bool eventsWereRunning = false;
for (auto timerIt = timerEventScripts.cbegin(); timerIt != timerEventScripts.cend(); ++timerIt) {
fo::func::dev_printf("\n[TimedEventScripts] Event: %d", timerIt->time);
if (timerIt->isActive == false) continue;
if (currentTime >= timerIt->time) {
if (timedEvent) executeTimedEvents.push(timedEvent); // store a pointer to the currently running event
+6
View File
@@ -117,6 +117,12 @@ void MakeCalls(void* func, std::initializer_list<DWORD> addrs) {
}
}
void MakeJumps(void* func, std::initializer_list<DWORD> addrs) {
for (auto& addr : addrs) {
MakeJump(addr, func);
}
}
void SafeMemSet(DWORD addr, BYTE val, int len) {
DWORD oldProtect;
+1
View File
@@ -61,5 +61,6 @@ void BlockCall(DWORD addr);
void HookCalls(void* func, std::initializer_list<DWORD> addrs);
void MakeCalls(void* func, std::initializer_list<DWORD> addrs);
void MakeJumps(void* func, std::initializer_list<DWORD> addrs);
}