camera: fix unchecked NO_HEIGHT usage

This resolves an OG bug whereby the camera shift could result in
extremely large values when NO_HEIGHT is involved, hence resulting in
the camera going out of bounds for a frame or so. We now check for this
case and use the previous valid Y position of the camera.

Resolves #1034.
This commit is contained in:
lahm86 2025-02-27 18:30:28 +00:00
parent df672ec16f
commit 798dc168f0
7 changed files with 50 additions and 43 deletions

View file

@ -1,6 +1,7 @@
## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr1-4.8.3...develop) - ××××-××-××
- added support for custom levels to use `disable_floor` in the gameflow, similar to TR2's Floating Islands (#2541)
- changed the Controls screen to hide the reset and unbind texts when changing a key (#2103)
- fixed several instances of the camera going out of bounds (#1034)
- fixed the bear AI fix option being applied in the Vilcabamba demo (#2559, regression from 4.8)
## [4.8.3](https://github.com/LostArtefacts/TRX/compare/tr1-4.8.2...tr1-4.8.3) - 2025-02-17

View file

@ -437,6 +437,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
- fixed triggered flip effects not working if there are no sound devices
- fixed ceiling heights at times being miscalculated, resulting in camera issues and Lara being able to jump into the ceiling
- fixed the camera being thrown through doors for one frame when looked at from fixed camera positions
- fixed several instances of the camera going out of bounds
- fixed the ape not performing the vault animation when climbing
- fixed Natla's gun moving while she is in her semi death state
- fixed the bear pat attack so it does not miss Lara

View file

@ -2,6 +2,7 @@
- added a `/cheats` console command
- added a `/wireframe` console command (#2500)
- fixed smashed windows blocking enemy pathing after loading a save (#2535)
- fixed several instances of the camera going out of bounds (#1034)
- fixed a rare issue whereby Lara would be unable to move after disposing a flare (#2545, regression from 0.9)
- fixed flare pickups only adding one flare to Lara's inventory rather than six (#2551, regression from 0.9)
- fixed play any level causing the game to hang when no gym level is present (#2560, regression from 0.9)

View file

@ -67,6 +67,7 @@ game with new enhancements and features.
- fixed Lara prioritising throwing a spent flare while mid-air, so to avoid missing ledge grabs
- fixed Lara at times not being able to jump immediately after going from her walking to running animation
- fixed looking forward too far causing an upside down camera frame
- fixed several instances of the camera going out of bounds
- fixed Lara never stepping backwards off a step using her right foot
- fixed the following floor data issues:
- **Opera House**: fixed the trigger under item 203 to trigger it rather than item 204

View file

@ -288,32 +288,34 @@ static void M_EnsureEnvironment(void)
static void M_Move(const GAME_VECTOR *const ideal, const int32_t speed)
{
g_Camera.pos.x += (ideal->x - g_Camera.pos.x) / speed;
g_Camera.pos.z += (ideal->z - g_Camera.pos.z) / speed;
g_Camera.pos.y += (ideal->y - g_Camera.pos.y) / speed;
g_Camera.pos.room_num = ideal->room_num;
const GAME_VECTOR old_pos = g_Camera.pos;
GAME_VECTOR pos = g_Camera.pos;
pos.x += (ideal->x - pos.x) / speed;
pos.z += (ideal->z - pos.z) / speed;
pos.y += (ideal->y - pos.y) / speed;
pos.room_num = ideal->room_num;
Camera_SetChunky(false);
const SECTOR *sector = Room_GetSector(
g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z, &g_Camera.pos.room_num);
int32_t height =
Room_GetHeight(sector, g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z)
- GROUND_SHIFT;
if (g_Camera.pos.y >= height && ideal->y >= height) {
LOS_Check(&g_Camera.target, &g_Camera.pos);
sector = Room_GetSector(
g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z,
&g_Camera.pos.room_num);
height = Room_GetHeight(
sector, g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z)
- GROUND_SHIFT;
const SECTOR *sector = Room_GetSector(pos.x, pos.y, pos.z, &pos.room_num);
int32_t height = Room_GetHeight(sector, pos.x, pos.y, pos.z);
if (height == NO_HEIGHT) {
pos.y = old_pos.y;
pos.room_num = old_pos.room_num;
sector = Room_GetSector(pos.x, pos.y, pos.z, &pos.room_num);
height = Room_GetHeight(sector, pos.x, pos.y, pos.z);
}
int32_t ceiling =
Room_GetCeiling(sector, g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z)
+ GROUND_SHIFT;
height -= STEP_L;
if (pos.y >= height && ideal->y >= height) {
LOS_Check(&g_Camera.target, &pos);
sector = Room_GetSector(pos.x, pos.y, pos.z, &pos.room_num);
height = Room_GetHeight(sector, pos.x, pos.y, pos.z) - STEP_L;
}
g_Camera.pos = pos;
int32_t ceiling = Room_GetCeiling(sector, pos.x, pos.y, pos.z) + STEP_L;
if (height < ceiling) {
ceiling = (height + ceiling) >> 1;
height = ceiling;

View file

@ -123,7 +123,6 @@
#define END_BIT 0x8000
#define MIN_SQUARE SQUARE(WALL_L / 4) // = 65536
#define GROUND_SHIFT (STEP_L)
#define DEFAULT_RADIUS 10

View file

@ -123,32 +123,34 @@ void Camera_ResetPosition(void)
void Camera_Move(const GAME_VECTOR *target, int32_t speed)
{
g_Camera.pos.x += (target->x - g_Camera.pos.x) / speed;
g_Camera.pos.z += (target->z - g_Camera.pos.z) / speed;
g_Camera.pos.y += (target->y - g_Camera.pos.y) / speed;
g_Camera.pos.room_num = target->room_num;
const GAME_VECTOR old_pos = g_Camera.pos;
GAME_VECTOR pos = g_Camera.pos;
pos.x += (target->x - pos.x) / speed;
pos.z += (target->z - pos.z) / speed;
pos.y += (target->y - pos.y) / speed;
pos.room_num = target->room_num;
Camera_SetChunky(false);
const SECTOR *sector = Room_GetSector(
g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z, &g_Camera.pos.room_num);
int32_t height =
Room_GetHeight(sector, g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z)
- STEP_L;
if (g_Camera.pos.y >= height && target->y >= height) {
LOS_Check(&g_Camera.target, &g_Camera.pos);
sector = Room_GetSector(
g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z,
&g_Camera.pos.room_num);
height = Room_GetHeight(
sector, g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z)
- STEP_L;
const SECTOR *sector = Room_GetSector(pos.x, pos.y, pos.z, &pos.room_num);
int32_t height = Room_GetHeight(sector, pos.x, pos.y, pos.z);
if (height == NO_HEIGHT) {
pos.y = old_pos.y;
pos.room_num = old_pos.room_num;
sector = Room_GetSector(pos.x, pos.y, pos.z, &pos.room_num);
height = Room_GetHeight(sector, pos.x, pos.y, pos.z);
}
int32_t ceiling =
Room_GetCeiling(sector, g_Camera.pos.x, g_Camera.pos.y, g_Camera.pos.z)
+ STEP_L;
height -= STEP_L;
if (pos.y >= height && target->y >= height) {
LOS_Check(&g_Camera.target, &pos);
sector = Room_GetSector(pos.x, pos.y, pos.z, &pos.room_num);
height = Room_GetHeight(sector, pos.x, pos.y, pos.z) - STEP_L;
}
g_Camera.pos = pos;
int32_t ceiling = Room_GetCeiling(sector, pos.x, pos.y, pos.z) + STEP_L;
if (height < ceiling) {
ceiling = (height + ceiling) >> 1;
height = ceiling;