From fb16e522f311ab50e1c89b19f4a6532f26e6077c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 17:33:31 +0000 Subject: [PATCH 1/7] Initial plan From 95600f90224e6147fe721dbc4cf6c30d66b76c30 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 17:35:58 +0000 Subject: [PATCH 2/7] Increase flyby camera limit from 256 to 1024 Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- TombEngine/Game/spotcam.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Game/spotcam.h b/TombEngine/Game/spotcam.h index 07917c26d5..9363db4a3f 100644 --- a/TombEngine/Game/spotcam.h +++ b/TombEngine/Game/spotcam.h @@ -2,7 +2,7 @@ #include "Math/Math.h" #include "Specific/clock.h" -constexpr auto MAX_SPOTCAMS = 256; +constexpr auto MAX_SPOTCAMS = 1024; constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 1.0f / 16; constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / FPS; From 8c7fc7c665467ff88810dc97e7d77e63da42777c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 19:12:52 +0000 Subject: [PATCH 3/7] Convert SpotCam arrays to std::vector for dynamic allocation Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- TombEngine/Game/spotcam.cpp | 14 +++++++------- TombEngine/Game/spotcam.h | 8 ++++---- TombEngine/Specific/level.cpp | 7 ++++++- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/TombEngine/Game/spotcam.cpp b/TombEngine/Game/spotcam.cpp index 96e6b8b612..033dc5830c 100644 --- a/TombEngine/Game/spotcam.cpp +++ b/TombEngine/Game/spotcam.cpp @@ -50,9 +50,9 @@ int LastSpotCamSequence; int LaraHealth; int LaraAir; int CurrentSpotcamSequence; -SPOTCAM SpotCam[MAX_SPOTCAMS]; -int SpotCamRemap[MAX_SPOTCAMS]; -int CameraCnt[MAX_SPOTCAMS]; +std::vector SpotCam; +std::vector SpotCamRemap; +std::vector CameraCnt; int NumberSpotcams; bool CheckTrigger = false; @@ -67,9 +67,9 @@ void ClearSpotCamSequences() SpotcamDontDrawLara = false; SpotcamOverlay = false; - - for (int i = 0; i < MAX_SPOTCAMS; i++) - SpotCam[i] = {}; + SpotCam.clear(); + SpotCamRemap.clear(); + CameraCnt.clear(); } void InitializeSpotCamSequences(bool startFirstSequence) @@ -848,7 +848,7 @@ Pose GetCameraTransform(int sequence, float alpha, bool loop) alpha = std::clamp(alpha, 0.0f, 1.0f); - if (sequence < 0 || sequence >= MAX_SPOTCAMS) + if (sequence < 0 || sequence >= SpotCamRemap.size()) { TENLog("Wrong flyby sequence number provided for getting camera coordinates.", LogLevel::Warning); return Pose::Zero; diff --git a/TombEngine/Game/spotcam.h b/TombEngine/Game/spotcam.h index 9363db4a3f..067a916e29 100644 --- a/TombEngine/Game/spotcam.h +++ b/TombEngine/Game/spotcam.h @@ -1,8 +1,8 @@ #pragma once #include "Math/Math.h" #include "Specific/clock.h" +#include -constexpr auto MAX_SPOTCAMS = 1024; constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 1.0f / 16; constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / FPS; @@ -47,9 +47,9 @@ enum SPOTCAM_FLAGS SCF_CAMERA_ONE_SHOT = (1 << 15), }; -extern SPOTCAM SpotCam[MAX_SPOTCAMS]; -extern int SpotCamRemap[MAX_SPOTCAMS]; -extern int CameraCnt[MAX_SPOTCAMS]; +extern std::vector SpotCam; +extern std::vector SpotCamRemap; +extern std::vector CameraCnt; extern int LastSpotCamSequence; extern int NumberSpotcams; extern bool UseSpotCam; diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 835836fcb3..ed930127ee 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -607,7 +607,12 @@ void LoadCameras() // TODO: Read properly! if (NumberSpotcams != 0) - ReadBytes(SpotCam, NumberSpotcams * sizeof(SPOTCAM)); + { + SpotCam.resize(NumberSpotcams); + SpotCamRemap.resize(NumberSpotcams); + CameraCnt.resize(NumberSpotcams); + ReadBytes(SpotCam.data(), NumberSpotcams * sizeof(SPOTCAM)); + } int sinkCount = ReadCount(); TENLog("Sink count: " + std::to_string(sinkCount), LogLevel::Info); From 2079407a73208b5e9252748028180eec03571c9c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 19:14:06 +0000 Subject: [PATCH 4/7] Fix SpotCamRemap sizing to handle sequence numbers correctly Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- TombEngine/Specific/level.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index ed930127ee..3ef37472e5 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -609,8 +609,9 @@ void LoadCameras() if (NumberSpotcams != 0) { SpotCam.resize(NumberSpotcams); - SpotCamRemap.resize(NumberSpotcams); - CameraCnt.resize(NumberSpotcams); + // SpotCamRemap is indexed by sequence number (unsigned char), so size it to 256 + SpotCamRemap.resize(256); + CameraCnt.resize(256); ReadBytes(SpotCam.data(), NumberSpotcams * sizeof(SPOTCAM)); } From 22a1fdfa0582d5adf9d953d7bb2e3ba8ee042c2c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 19:15:12 +0000 Subject: [PATCH 5/7] Add SPOTCAM_MAX_SEQUENCE_ID constant for better code maintainability Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- TombEngine/Game/spotcam.h | 1 + TombEngine/Specific/level.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/TombEngine/Game/spotcam.h b/TombEngine/Game/spotcam.h index 067a916e29..1f406884e0 100644 --- a/TombEngine/Game/spotcam.h +++ b/TombEngine/Game/spotcam.h @@ -3,6 +3,7 @@ #include "Specific/clock.h" #include +constexpr auto SPOTCAM_MAX_SEQUENCE_ID = 256; // Max value for unsigned char sequence field constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 1.0f / 16; constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / FPS; diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 3ef37472e5..97ab4f41a4 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -609,9 +609,9 @@ void LoadCameras() if (NumberSpotcams != 0) { SpotCam.resize(NumberSpotcams); - // SpotCamRemap is indexed by sequence number (unsigned char), so size it to 256 - SpotCamRemap.resize(256); - CameraCnt.resize(256); + // SpotCamRemap and CameraCnt are indexed by sequence number (unsigned char 0-255) + SpotCamRemap.resize(SPOTCAM_MAX_SEQUENCE_ID); + CameraCnt.resize(SPOTCAM_MAX_SEQUENCE_ID); ReadBytes(SpotCam.data(), NumberSpotcams * sizeof(SPOTCAM)); } From 9416c6a948090cc367ef8feb610224d840176899 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 19:15:56 +0000 Subject: [PATCH 6/7] Initialize SpotCamRemap and CameraCnt vectors with zero values Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- TombEngine/Specific/level.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 97ab4f41a4..c6137dd85d 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -610,8 +610,9 @@ void LoadCameras() { SpotCam.resize(NumberSpotcams); // SpotCamRemap and CameraCnt are indexed by sequence number (unsigned char 0-255) - SpotCamRemap.resize(SPOTCAM_MAX_SEQUENCE_ID); - CameraCnt.resize(SPOTCAM_MAX_SEQUENCE_ID); + // Initialize with 0 to match behavior of original static arrays + SpotCamRemap.assign(SPOTCAM_MAX_SEQUENCE_ID, 0); + CameraCnt.assign(SPOTCAM_MAX_SEQUENCE_ID, 0); ReadBytes(SpotCam.data(), NumberSpotcams * sizeof(SPOTCAM)); } From d947271f34d38c676f08343f027e179d1aefa264 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 19:17:09 +0000 Subject: [PATCH 7/7] Fix bounds check and ensure vectors are always initialized Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- TombEngine/Game/spotcam.cpp | 2 +- TombEngine/Specific/level.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/TombEngine/Game/spotcam.cpp b/TombEngine/Game/spotcam.cpp index 033dc5830c..9d5b5d1019 100644 --- a/TombEngine/Game/spotcam.cpp +++ b/TombEngine/Game/spotcam.cpp @@ -848,7 +848,7 @@ Pose GetCameraTransform(int sequence, float alpha, bool loop) alpha = std::clamp(alpha, 0.0f, 1.0f); - if (sequence < 0 || sequence >= SpotCamRemap.size()) + if (sequence < 0 || sequence >= SPOTCAM_MAX_SEQUENCE_ID) { TENLog("Wrong flyby sequence number provided for getting camera coordinates.", LogLevel::Warning); return Pose::Zero; diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index c6137dd85d..76ae5999f4 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -605,14 +605,15 @@ void LoadCameras() NumberSpotcams = ReadCount(); + // SpotCamRemap and CameraCnt are indexed by sequence number (unsigned char 0-255) + // Always initialize them to handle GetCameraTransform calls even when NumberSpotcams == 0 + SpotCamRemap.assign(SPOTCAM_MAX_SEQUENCE_ID, 0); + CameraCnt.assign(SPOTCAM_MAX_SEQUENCE_ID, 0); + // TODO: Read properly! if (NumberSpotcams != 0) { SpotCam.resize(NumberSpotcams); - // SpotCamRemap and CameraCnt are indexed by sequence number (unsigned char 0-255) - // Initialize with 0 to match behavior of original static arrays - SpotCamRemap.assign(SPOTCAM_MAX_SEQUENCE_ID, 0); - CameraCnt.assign(SPOTCAM_MAX_SEQUENCE_ID, 0); ReadBytes(SpotCam.data(), NumberSpotcams * sizeof(SPOTCAM)); }