-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libtrx/anims/frames: migrate TR2 frame handling to TRX #2246
Conversation
Download the built assets for this pull request: |
GameBuf_Alloc(sizeof(int16_t) * (frame_size - 9), GBUF_ANIM_FRAMES); | ||
memcpy(frame->mesh_rots, data_ptr, sizeof(int16_t) * (frame_size - 9)); | ||
data_ptr += MAX(0, frame_size - (data_ptr - frame_start)); | ||
#else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this if test in the code below in the else still needed? Because the if above already checks for TR_VERSION > 1
#if TR_VERSION == 1
mesh_count = *data_ptr++;
#endif
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be tidying up this function after this, it's a bit untidy atm until we get TR2 rotations expanded and BOUNDS_16
working the same as TR1. The #if
s will become neater then. I could remove now but would re-introduce it more or less immediately anyway.
I've tested with swapping saves between TR2X and OG, all LGTM. I also found a small issue in the PR build that isn't present in latest dev snapshot, and similar to #1906. It looks like the mercenary's shot is hitting Lara in a different spot which causes the blood splatter to shift to another part of the screen. |
Thank @aredfan. I think this is a nasty bug, and I believe OG might actually be incorrect. Tagging @rr, @walkawayy for thoughts on this. I've done some logging on the dev snapshot and this PR, and you're exactly right, the blood is spawning in a different place. Everything else matches up. PR Dev The issue I believe is in I don't think we can match OG here if we are going to have structured frames in all honesty. Once we get to expanding frames, the padding is even more meaningless because we don't know what to assign it as. |
Hm so this has the potential to affect where blood spawns in normal gameplay as well, not just demos? It does seem like a bug that Btw it also looks like it could affect TR1 since it uses the same formula: Line 172 in 3362551
|
Yeah, it's a TR1 issue too. But because frames aren't padded there we're still getting the same results as before, but still, we are reading into data we shouldn't be. diff --git a/src/tr2/game/collide.c b/src/tr2/game/collide.c
index 5c76d797..0eb61e83 100644
--- a/src/tr2/game/collide.c
+++ b/src/tr2/game/collide.c
@@ -579,7 +579,9 @@ void Collide_GetJointAbsPosition(
Matrix_RotYXZsuperpack(&mesh_rots, 0);
const int16_t *extra_rotation = item->data;
- for (int32_t i = 0; i < joint; i++) {
+ int32_t abs_joint = joint;
+ CLAMP(abs_joint, 0, object->mesh_count);
+ for (int32_t i = 0; i < abs_joint; i++) {
const ANIM_BONE *const bone = Object_GetBone(object, i);
if (bone->matrix_pop) {
Matrix_Pop();
diff --git a/src/tr2/game/spawn.c b/src/tr2/game/spawn.c
index ba64ac86..1521a59a 100644
--- a/src/tr2/game/spawn.c
+++ b/src/tr2/game/spawn.c
@@ -143,9 +143,13 @@ int16_t Spawn_GunHit(
const int32_t x, const int32_t y, const int32_t z, const int16_t speed,
const int16_t y_rot, const int16_t room_num)
{
- XYZ_32 vec = {};
+ XYZ_32 vec = {
+ .x = 50 * (Random_GetDraw() - 0x4000) / 0x4000,
+ .y = 50 * (Random_GetDraw() - 0x4000) / 0x4000,
+ .z = 50 * (Random_GetDraw() - 0x4000) / 0x4000,
+ };
Collide_GetJointAbsPosition(
- g_LaraItem, &vec, Random_GetControl() * 25 / 0x7FFF);
+ g_LaraItem, &vec, Random_GetControl() * LM_NUMBER_OF / 0x7FFF);
Spawn_Blood(
vec.x, vec.y, vec.z, g_LaraItem->speed, g_LaraItem->rot.y,
g_LaraItem->room_num); |
Don't the additional Random() calls cause the OG demos to desync? |
It would change visuals only as it's |
I can't think of any other way out of this. Let's proceed, as long as the rest of the demos appear normal. |
Will PR separately and rebase this one later. |
The frame_base is not required to be saved or loaded for Lara's arms, because it is set on each frame anyway. Removes a dependency on g_AnimFrames, similar to TR1.
This migrates animation frame storage to TRX and changes the way frames are interpreted. All previous casting to ANIM_FRAME is now handled normally throughout the TR2 codebase. Rotations remain unparsed, this will be tackled separately.
This removes the separate checks for handling interpolation and frame size on animations.
Rebased, @aredfan, if you fancy doing a check. Develop build below on left, PR on right. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased, @aredfan, if you fancy doing a check. Develop build below on left, PR on right.
Np and happy to check, I can confirm the position Lara gets shot matches your screenshots. I understand the demo will be slightly different visually and that's perfectly fine.
LGTM, and thank you again. 👍
Thanks. This was a great find, good to get it fixed 😌 |
Checklist
Description
This moves TR2 frame handling into TRX. We retain the original (super)packed rotations for the time being, this will be tackled on its own. Apologies that this is mostly one fairly large commit - everything was so dependent I couldn't see a way to split it up further.
There is a workaround added for objects like the prayer wheel, which do not have any animations. Because we set the object's frame base while iterating animations, the wheel remained with a null pointer. The workaround is to store the frame offset while reading the level, then later point it to the matching animation (and to clarify, the wheel points to the flare pack's animation - we will fix this in the future with injections).
I've removed
frame_base
from the savegame (well, we're now skipping reading and just writing a 0) in line with TR1. This is set on each frame anyway and I've confirmed by saving in TR2X while using a gun for example, then loading it in OG, plus vice-versa. I'd appreciate some other tests around saving/loading while Lara's arms are busy with guns/flares.Once this lands, we can migrate TR2's
BOUNDS16
to match TR1, which means we can streamline things likeM_ParseFrame
.