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 template to SafeWrite.h and devlog_f to Logging.cpp.

Minor code edits.
This commit is contained in:
NovaRain
2020-08-17 15:11:16 +08:00
parent f1102afbc3
commit a35487d0aa
15 changed files with 119 additions and 39 deletions
+38
View File
@@ -2760,6 +2760,39 @@ 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:[_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_OnGameLoad() {
dudeIsAnimDeath = false;
}
void BugFixesInit()
{
#ifndef NDEBUG
@@ -3494,4 +3527,9 @@ void BugFixesInit()
// 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);
}
+2 -1
View File
@@ -1,10 +1,11 @@
#pragma once
void BugFixesInit();
void BugFixes_OnGameLoad();
void BugFixes_Initialization();
void DrugsSaveFix(HANDLE file);
bool DrugsLoadFix(HANDLE file);
void ResetBodyState();
void BugFixes_Initialization();
extern int tagSkill4LevelBase;
+1 -1
View File
@@ -812,7 +812,7 @@ const DWORD xvfprintf_ = 0x4DF1AC;
// WRAPPERS
// please, use CamelCase for those
// 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) DevPrintf(const char* fmt, ...) {
__asm jmp debug_printf_;
+1 -1
View File
@@ -1111,8 +1111,8 @@ extern const DWORD xvfprintf_;
// WRAPPERS:
// TODO: move these to different namespace
// Prints debug message to debug.log file for develop build
#ifndef NDEBUG
// Prints debug message to game debug.log file for develop build
void DevPrintf(const char* fmt, ...);
#else
void DevPrintf(...);
+1 -1
View File
@@ -31,9 +31,9 @@ extern bool AviMovieWidthFit;
extern IDirect3D9* d3d9;
extern IDirect3DDevice9* d3d9Device;
void Graphics_OnGameLoad();
void GraphicsInit();
void GraphicsExit();
void Graphics_OnGameLoad();
long Gfx_GetGameWidthRes();
long Gfx_GetGameHeightRes();
+21 -26
View File
@@ -86,22 +86,19 @@ static 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 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) {
@@ -115,11 +112,10 @@ static 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;
@@ -150,18 +146,16 @@ static 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);
}
}
@@ -1595,10 +1589,11 @@ void __stdcall RegisterHook(TProgram* script, int id, int procNum, bool specReg)
}
static void LoadHookScript(const char* name, int id) {
if (id >= numHooks || IsGameScript(name)) return;
//if (id >= numHooks || IsGameScript(name)) return;
char filename[MAX_PATH];
sprintf(filename, "scripts\\%s.int", name);
if (DbAccess(filename)) {
sScriptProgram prog;
dlog("> ", DL_HOOK);
+1 -1
View File
@@ -2,5 +2,5 @@
void InterfaceInit();
void InterfaceExit();
void InterfaceGmouseHandleHook();
void Interface_OnGameLoad();
void InterfaceGmouseHandleHook();
+1
View File
@@ -86,6 +86,7 @@ void ClearLoopFlag(LoopFlag flag) {
}
static void __stdcall ResetState(DWORD onLoad) { // OnGameReset & OnBeforeGameStart
BugFixes_OnGameLoad();
if (GraphicsMode > 3) Graphics_OnGameLoad();
ForceGraphicsRefresh(0); // disable refresh
LoadOrder_OnGameLoad();
+18 -1
View File
@@ -40,7 +40,7 @@ void dlogr(const char* 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);
@@ -52,6 +52,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, ddrawIniDef)) {
+9 -1
View File
@@ -27,7 +27,15 @@
void dlog(const char* msg, int type);
void dlogr(const char* msg, 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();
#else
#define dlog(a,b)
+6
View File
@@ -693,6 +693,12 @@ void MiscPatchesInit() {
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();
+13 -1
View File
@@ -45,7 +45,7 @@ void MakeJump(DWORD addr, void* func);
void MakeJump(DWORD addr, void* func, int len);
void BlockCall(DWORD addr);
// emulation of 4.x HookCalls/MakeCalls
// emulation of 4.x HookCalls/MakeCalls/MakeJumps
template <class ForwardIteratorType>
void HookCalls(void* func, ForwardIteratorType begin, ForwardIteratorType end) {
@@ -70,3 +70,15 @@ template <size_t N>
void MakeCalls(void* func, const DWORD (&addrs)[N]) {
MakeCalls(func, std::begin(addrs), std::end(addrs));
}
template <class ForwardIteratorType>
void MakeJumps(void* func, ForwardIteratorType begin, ForwardIteratorType end) {
for (ForwardIteratorType it = begin; it != end; ++it) {
MakeJump(*it, func);
}
}
template <size_t N>
void MakeJumps(void* func, const DWORD (&addrs)[N]) {
MakeJumps(func, std::begin(addrs), std::end(addrs));
}
+3 -1
View File
@@ -1505,10 +1505,12 @@ static DWORD HandleTimedEventScripts() {
executeTimedEventDepth++;
DevPrintf("\n[TimedEventScripts] Time: %d / Depth: %d", currentTime, executeTimedEventDepth);
for (std::list<TimedEvent>::const_iterator it = timerEventScripts.cbegin(); it != timerEventScripts.cend(); ++it) {
DevPrintf("\n[TimedEventScripts] Event: %d", it->time);
}
bool eventsWereRunning = false;
for (std::list<TimedEvent>::const_iterator timerIt = timerEventScripts.cbegin(); timerIt != timerEventScripts.cend(); ++timerIt) {
DevPrintf("\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
+3 -3
View File
@@ -145,8 +145,8 @@ static void __declspec(naked) __stdcall ProtoPtr(DWORD pid, int** proto) {
}
static void __stdcall StatRecalcDerived(TGameObj* critter) {
int basestats[7];
for (int i = STAT_st; i <= STAT_lu; i++) basestats[i] = StatLevel(critter, i);
int baseStats[7];
for (int i = STAT_st; i <= STAT_lu; i++) baseStats[i] = StatLevel(critter, i);
int* proto;
ProtoPtr(critter->protoId, &proto);
@@ -156,7 +156,7 @@ static void __stdcall StatRecalcDerived(TGameObj* critter) {
double sum = 0;
for (int j = STAT_st; j <= STAT_lu; j++) {
sum += (basestats[j] + StatShifts[i * 7 + j]) * StatMulti[i * 7 + j];
sum += (baseStats[j] + StatShifts[i * 7 + j]) * StatMulti[i * 7 + j];
}
proto[i + 9] = StatFormulas[i * 2] + (int)floor(sum);
if (proto[i + 9] < StatFormulas[i * 2 + 1]) proto[i + 9] = StatFormulas[i * 2 + 1];
+1 -1
View File
@@ -18,8 +18,8 @@
#pragma once
void Stats_OnGameLoad();
void StatsInit();
void Stats_OnGameLoad();
long __stdcall GetStatMax(int stat, int isNPC);
long __stdcall GetStatMin(int stat, int isNPC);