From 12e937976f7793da08f31fde9156996de89bdc1c Mon Sep 17 00:00:00 2001 From: nukeulater Date: Sat, 30 Dec 2023 22:21:14 +0200 Subject: [PATCH] fix dead camera referencing "de-allocated" stack for the node position --- xlive/Blam/Engine/camera/dead_camera.cpp | 34 +++++++++++++++++++++++- xlive/Blam/Engine/objects/objects.cpp | 7 +++-- xlive/Blam/Engine/objects/objects.h | 2 +- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/xlive/Blam/Engine/camera/dead_camera.cpp b/xlive/Blam/Engine/camera/dead_camera.cpp index cfb6d8414..05dc55b0a 100644 --- a/xlive/Blam/Engine/camera/dead_camera.cpp +++ b/xlive/Blam/Engine/camera/dead_camera.cpp @@ -4,8 +4,40 @@ #include "Blam/Engine/objects/objects.h" #include "Util/Hooks/Hook.h" +real_point3d* __cdecl object_try_and_get_interpolated_position(datum object_index, int16 node_index, real_point3d* out_pos) +{ + real_matrix4x3 out_mat = *object_try_get_node_matrix_interpolated(object_index, node_index, &out_mat); + *out_pos = out_mat.position; + return out_pos; +} + +__declspec(naked) void object_try_get_node_position_interpolated_intermediate() +{ +#define current_stack_offset (2Ch + 4h + 4h) + __asm + { + // grab the out position mem address at 0x0C + mov eax, [esp + 4 + current_stack_offset + 0Ch] + add eax, 4 // go to position offset + push eax + // grab the rest of the parameters + mov eax, [esp + 4 + 4 + 4] + push eax // node index + mov eax, [esp + 4 + 4 + 4] + push eax // object index + call object_try_and_get_interpolated_position + add esp, 4 * 3 + // copy ptr of the data in esi + mov esi, [esp + 4 + current_stack_offset + 0Ch] + retn + } +#undef current_stack_offset (0Ch) +} + void apply_dead_camera_patches() { // Patch call inside dead_camera update to try and get interpolated node matrix from the current target_datum - PatchCall(Memory::GetAddress(0xCDBAE), object_try_get_node_matrix_interpolated); + PatchCall(Memory::GetAddress(0xCDBAE), object_try_get_node_position_interpolated_intermediate); + // nop the rest of the unneeded instructions + NopFill(Memory::GetAddress(0xCDBB3), 22); } diff --git a/xlive/Blam/Engine/objects/objects.cpp b/xlive/Blam/Engine/objects/objects.cpp index 05ff429e8..4955241f1 100644 --- a/xlive/Blam/Engine/objects/objects.cpp +++ b/xlive/Blam/Engine/objects/objects.cpp @@ -780,12 +780,11 @@ real_matrix4x3* object_get_node_matrix(datum object_index, int16 node_index) return &nodes[node_index]; } -real_matrix4x3* object_try_get_node_matrix_interpolated(datum object_index, int16 node_index) +real_matrix4x3* object_try_get_node_matrix_interpolated(datum object_index, int16 node_index, real_matrix4x3* out_mat) { - real_matrix4x3 result; - if (halo_interpolator_interpolate_object_node_matrix(object_index, node_index, &result)) + if (halo_interpolator_interpolate_object_node_matrix(object_index, node_index, out_mat)) { - return &result; + return out_mat; } else { diff --git a/xlive/Blam/Engine/objects/objects.h b/xlive/Blam/Engine/objects/objects.h index 1a960015b..725784241 100644 --- a/xlive/Blam/Engine/objects/objects.h +++ b/xlive/Blam/Engine/objects/objects.h @@ -277,7 +277,7 @@ void object_get_origin_interpolated(datum object_index, real_point3d* point_out) real_matrix4x3* object_get_node_matrix(datum object_datum, int16 node_index); -real_matrix4x3* object_try_get_node_matrix_interpolated(datum object_index, int16 node_index); +real_matrix4x3* object_try_get_node_matrix_interpolated(datum object_index, int16 node_index, real_matrix4x3* out_mat); real_matrix4x3* object_get_node_matrices(datum object_datum, int32* out_node_count);