From 507ba41a26452b85868e60d1ade1ad0d6858710d Mon Sep 17 00:00:00 2001 From: Max Roncace Date: Thu, 2 Apr 2026 23:06:32 -0400 Subject: [PATCH] Fix crash when first talking to Fyrus The animation metadata passed into playExpression is invalid and causes a junk pointer to be read, triggering a segfault. --- src/d/actor/d_a_npc_grz.cpp | 10 +++++++++- src/d/actor/d_a_npc_tks.cpp | 8 +++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/d/actor/d_a_npc_grz.cpp b/src/d/actor/d_a_npc_grz.cpp index c245340c4c..104c0c4756 100644 --- a/src/d/actor/d_a_npc_grz.cpp +++ b/src/d/actor/d_a_npc_grz.cpp @@ -1363,7 +1363,15 @@ void daNpc_Grz_c::playExpression() { daNpcF_anmPlayData dat7 = {ANM_LIEDOWN, mpHIO->m.common.morf_frame, 0}; daNpcF_anmPlayData* pDat7[1] = {&dat7}; daNpcF_anmPlayData dat8 = {ANM_GETUP, mpHIO->m.common.morf_frame, 1}; - daNpcF_anmPlayData* pDat8[1] = {&dat8}; +#if TARGET_PC + // BUG: If mNumLoops is non-zero, the data array MUST be null-terminated to prevent + // playExpression from reading junk when it increments the index. + // For some reason this doesn't crash on hardware, but it triggers a segfault on PC + // when first talking to Fyrus after defating him. + daNpcF_anmPlayData* pDat8[2] = {&dat8, NULL}; +#else + daNpcF_anmPlayData* pDat8[2] = {&dat8}; +#endif daNpcF_anmPlayData dat9 = {ANM_F_WEAK_WAIT, mpHIO->m.common.morf_frame, 0}; daNpcF_anmPlayData* pDat9[1] = {&dat9}; daNpcF_anmPlayData dat10 = {ANM_NONE, mpHIO->m.common.morf_frame, 0}; diff --git a/src/d/actor/d_a_npc_tks.cpp b/src/d/actor/d_a_npc_tks.cpp index f1c33003f8..9b0ee4af70 100644 --- a/src/d/actor/d_a_npc_tks.cpp +++ b/src/d/actor/d_a_npc_tks.cpp @@ -824,9 +824,11 @@ void daNpcTks_c::playMotion() { daNpcF_anmPlayData dat4b = {ANM_FLY, 0.0f, 0}; daNpcF_anmPlayData* pDat4[2] = {&dat4a, &dat4b}; - #if TARGET_PC - // Note: this fixes a crash in the cutscene after entering city and likely needs to be revisited as its - // unclear why this was 1 in the first place and unclear why this fixes it +#if TARGET_PC + // BUG: If mNumLoops is non-zero, the data array MUST be null-terminated to prevent + // playExpression from reading junk when it increments the index. + // For some reason this doesn't crash on hardware, but it triggers a segfault on PC + // in the cutscene after entering city. daNpcF_anmPlayData dat5 = {ANM_JUMP_E, 0.0f, 0}; #else daNpcF_anmPlayData dat5 = {ANM_JUMP_E, 0.0f, 1};