Skip to content

Commit

Permalink
tr2/rooms: fix crash when drawing too many rooms
Browse files Browse the repository at this point in the history
Resolves #1998.
  • Loading branch information
rr- committed Dec 9, 2024
1 parent 957bcd4 commit b06a69f
Show file tree
Hide file tree
Showing 16 changed files with 63 additions and 48 deletions.
1 change: 1 addition & 0 deletions docs/tr2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
- fixed a potential crash if Lara is on the skidoo in a room with many other adjoining rooms (#1987)
- fixed a softlock in Home Sweet Home if the final cutscene is triggered while Lara is on water surface (#1701)
- fixed Lara's left arm becoming stuck if a flare is drawn just before the final cutscene in Home Sweet Home (#1992)
- fixed game crash when trying to draw too many rooms at once (#1998)
- removed unused detail level option

## [0.6](https://github.com/LostArtefacts/TRX/compare/tr2-0.5...tr2-0.6) - 2024-11-06
Expand Down
4 changes: 2 additions & 2 deletions docs/tr2/progress.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions docs/tr2/progress.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3041,7 +3041,7 @@ typedef enum {
# game/cinema.c
0x00411F50 0x000A + void __cdecl Game_SetCutsceneTrack(int32_t track);
0x00411F60 0x0112 + int32_t __cdecl Game_Cutscene_Start(int32_t level_num);
0x00412080 0x0093 +R void __cdecl Misc_InitCinematicRooms(void);
0x00412080 0x0093 + void __cdecl Room_InitCinematic(void);
0x00412120 0x016F + int32_t __cdecl Game_Cutscene_Control(int32_t nframes);
0x00412290 0x0138 + void __cdecl Camera_UpdateCutscene(void);
0x004123D0 0x007F +R int32_t __cdecl Room_FindByPos(int32_t x, int32_t y, int32_t z);
Expand Down Expand Up @@ -4541,8 +4541,8 @@ typedef enum {
0x005263C8 - uint16_t *g_Overlap;
0x005206C0 - CREATURE *g_BaddieSlots;
0x00526312 + int16_t g_CineLevelID;
0x005252B8 - int32_t g_DrawRoomsCount;
0x00525B20 - int16_t g_DrawRoomsArray[100];
0x005252B8 + int32_t g_DrawRoomsCount;
0x00525B20 + int16_t g_DrawRoomsArray[100];
0x00525BEC - int32_t g_DynamicLightCount;
0x004D7784 - int32_t g_CineTickCount;
0x004D7788 - int32_t g_OriginalRoom;
Expand Down
20 changes: 1 addition & 19 deletions src/tr2/decomp/decomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ int32_t __cdecl Game_Cutscene_Start(const int32_t level_num)
return 2;
}

Misc_InitCinematicRooms();
Room_InitCinematic();
CutscenePlayer1_Initialise(g_Lara.item_num);
g_Camera.target_angle = g_CineTargetAngle;

Expand Down Expand Up @@ -929,24 +929,6 @@ int32_t __cdecl Game_Cutscene_Start(const int32_t level_num)
return result;
}

void __cdecl Misc_InitCinematicRooms(void)
{
for (int32_t i = 0; i < g_RoomCount; i++) {
const int16_t flipped_room = g_Rooms[i].flipped_room;
if (flipped_room != NO_ROOM_NEG) {
g_Rooms[flipped_room].bound_active = 1;
}
g_Rooms[i].flags |= RF_OUTSIDE;
}

g_DrawRoomsCount = 0;
for (int32_t i = 0; i < g_RoomCount; i++) {
if (!g_Rooms[i].bound_active) {
g_DrawRoomsArray[g_DrawRoomsCount++] = i;
}
}
}

int32_t __cdecl Game_Cutscene_Control(const int32_t nframes)
{
g_CineTickCount += g_CineTickRate * nframes;
Expand Down
1 change: 0 additions & 1 deletion src/tr2/decomp/decomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ bool __cdecl WinVidGoWindowed(
void __cdecl WinVidSetDisplayAdapter(DISPLAY_ADAPTER *disp_adapter);
void __cdecl Game_SetCutsceneTrack(int32_t track);
int32_t __cdecl Game_Cutscene_Start(int32_t level_num);
void __cdecl Misc_InitCinematicRooms(void);
int32_t __cdecl Game_Cutscene_Control(int32_t nframes);
void __cdecl CutscenePlayer_Control(int16_t item_num);
void __cdecl Lara_Control_Cutscene(int16_t item_num);
Expand Down
4 changes: 2 additions & 2 deletions src/tr2/game/collide.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ int32_t __cdecl Collide_CollideStaticObjects(

Room_GetNearbyRooms(x, y, z, coll->radius + 50, height + 50, room_num);

for (int32_t i = 0; i < g_DrawRoomsCount; i++) {
const ROOM *const room = &g_Rooms[g_DrawRoomsArray[i]];
for (int32_t i = 0; i < g_RoomsToDrawCount; i++) {
const ROOM *const room = &g_Rooms[g_RoomsToDraw[i]];

for (int32_t j = 0; j < room->num_static_meshes; j++) {
const STATIC_MESH *const mesh = &room->static_meshes[j];
Expand Down
1 change: 1 addition & 0 deletions src/tr2/game/game.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "game/lara/control.h"
#include "game/music.h"
#include "game/overlay.h"
#include "game/room.h"
#include "game/room_draw.h"
#include "game/shell.h"
#include "game/sound.h"
Expand Down
33 changes: 22 additions & 11 deletions src/tr2/game/room.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <libtrx/debug.h>
#include <libtrx/utils.h>

void Room_MarkToBeDrawn(int16_t room_num);
static int16_t M_GetFloorTiltHeight(const SECTOR *sector, int32_t x, int32_t z);
static int16_t M_GetCeilingTiltHeight(
const SECTOR *sector, int32_t x, int32_t z);
Expand Down Expand Up @@ -487,8 +488,8 @@ void __cdecl Room_GetNearbyRooms(
const int32_t x, const int32_t y, const int32_t z, const int32_t r,
const int32_t h, const int16_t room_num)
{
g_DrawRoomsArray[0] = room_num;
g_DrawRoomsCount = 1;
g_RoomsToDrawCount = 0;
Room_MarkToBeDrawn(room_num);

Room_GetNewRoom(r + x, y, r + z, room_num);
Room_GetNewRoom(x - r, y, r + z, room_num);
Expand All @@ -504,15 +505,7 @@ void __cdecl Room_GetNewRoom(
const int32_t x, const int32_t y, const int32_t z, int16_t room_num)
{
Room_GetSector(x, y, z, &room_num);

for (int32_t i = 0; i < g_DrawRoomsCount; i++) {
if (g_DrawRoomsArray[i] == room_num) {
return;
}
}

// TODO: fix crash when trying to draw too many rooms
g_DrawRoomsArray[g_DrawRoomsCount++] = room_num;
Room_MarkToBeDrawn(room_num);
}

int16_t __cdecl Room_GetTiltType(
Expand Down Expand Up @@ -888,3 +881,21 @@ ROOM *Room_Get(const int32_t room_num)
{
return &g_Rooms[room_num];
}

void Room_InitCinematic(void)
{
for (int32_t i = 0; i < g_RoomCount; i++) {
const int16_t flipped_room = g_Rooms[i].flipped_room;
if (flipped_room != NO_ROOM_NEG) {
g_Rooms[flipped_room].bound_active = 1;
}
g_Rooms[i].flags |= RF_OUTSIDE;
}

g_RoomsToDrawCount = 0;
for (int32_t i = 0; i < g_RoomCount; i++) {
if (!g_Rooms[i].bound_active) {
Room_MarkToBeDrawn(i);
}
}
}
3 changes: 3 additions & 0 deletions src/tr2/game/room.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ void __cdecl Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num);
int16_t __cdecl Room_GetTiltType(
const SECTOR *sector, int32_t x, int32_t y, int32_t z);

// TODO: poor abstraction
void Room_InitCinematic(void);

SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z);
SECTOR *Room_GetSkySector(const SECTOR *sector, int32_t x, int32_t z);
SECTOR *__cdecl Room_GetSector(
Expand Down
26 changes: 19 additions & 7 deletions src/tr2/game/room_draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@

#include <libtrx/utils.h>

void Room_MarkToBeDrawn(const int16_t room_num)
{
for (int32_t i = 0; i < g_RoomsToDrawCount; i++) {
if (g_RoomsToDraw[i] == room_num) {
return;
}
}

if (g_RoomsToDrawCount + 1 < MAX_ROOMS_TO_DRAW) {
g_RoomsToDraw[g_RoomsToDrawCount++] = room_num;
}
}

void __cdecl Room_GetBounds(void)
{
while (g_BoundStart != g_BoundEnd) {
Expand All @@ -32,8 +45,7 @@ void __cdecl Room_GetBounds(void)
}

if (!(r->bound_active & 1)) {
// TODO: fix crash when drawing too many rooms
g_DrawRoomsArray[g_DrawRoomsCount++] = room_num;
Room_MarkToBeDrawn(room_num);
r->bound_active |= 1;
if (r->flags & RF_OUTSIDE) {
g_Outside = RF_OUTSIDE;
Expand Down Expand Up @@ -467,7 +479,7 @@ void __cdecl Room_DrawAllRooms(const int16_t current_room)
g_BoundStart = 0;
g_BoundEnd = 1;

g_DrawRoomsCount = 0;
g_RoomsToDrawCount = 0;
g_Outside = r->flags & RF_OUTSIDE;

if (g_Outside) {
Expand Down Expand Up @@ -524,13 +536,13 @@ void __cdecl Room_DrawAllRooms(const int16_t current_room)
Lara_Draw(g_LaraItem);
}

for (int32_t i = 0; i < g_DrawRoomsCount; i++) {
const int16_t room_num = g_DrawRoomsArray[i];
for (int32_t i = 0; i < g_RoomsToDrawCount; i++) {
const int16_t room_num = g_RoomsToDraw[i];
Room_DrawSingleRoomGeometry(room_num);
}

for (int32_t i = 0; i < g_DrawRoomsCount; i++) {
const int16_t room_num = g_DrawRoomsArray[i];
for (int32_t i = 0; i < g_RoomsToDrawCount; i++) {
const int16_t room_num = g_RoomsToDraw[i];
Room_DrawSingleRoomObjects(room_num);
}
}
1 change: 1 addition & 0 deletions src/tr2/game/room_draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "global/types.h"

void Room_MarkToBeDrawn(int16_t room_num);
void __cdecl Room_GetBounds(void);
void __cdecl Room_SetBounds(
const int16_t *obj_ptr, int32_t room_num, const ROOM *parent);
Expand Down
1 change: 1 addition & 0 deletions src/tr2/global/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#define MAX_TEXTURES 2048
#define MAX_PALETTES 16
#define MAX_ROOMS 1024
#define MAX_ROOMS_TO_DRAW 100
#define MAX_FLIP_MAPS 10
#define MAX_VERTICES 0x2000
#define MAX_BOUND_ROOMS 128
Expand Down
3 changes: 3 additions & 0 deletions src/tr2/global/vars.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ const char *g_TR2XVersion = "TR2X (non-Docker build)";

GAME_FLOW_DIR g_GF_OverrideDir = (GAME_FLOW_DIR)-1;

int16_t g_RoomsToDraw[MAX_ROOMS_TO_DRAW] = { 0 };
int16_t g_RoomsToDrawCount = 0;

SDL_Window *g_SDLWindow = NULL;
3 changes: 3 additions & 0 deletions src/tr2/global/vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@
extern const char *g_TR2XVersion;
extern GAME_FLOW_DIR g_GF_OverrideDir;

extern int16_t g_RoomsToDraw[MAX_ROOMS_TO_DRAW];
extern int16_t g_RoomsToDrawCount;

extern SDL_Window *g_SDLWindow;
2 changes: 0 additions & 2 deletions src/tr2/global/vars_decomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@
#define g_AnimFrames (*(FRAME_INFO **)0x005251B0)
#define g_Meshes (*(int16_t ***)0x005252B0)
#define g_Outside (*(int32_t*)0x005252B4)
#define g_DrawRoomsCount (*(int32_t*)0x005252B8)
#define g_IMMatrixStack (*(MATRIX(*)[256])0x005252C0)
#define g_DoorVBuf (*(PORTAL_VBUF(*)[4])0x005258C0)
#define g_IMFrac (*(int32_t*)0x005258F0)
Expand All @@ -471,7 +470,6 @@
#define g_OutsideBottom (*(int32_t*)0x00525B00)
#define g_AnimRanges (*(ANIM_RANGE **)0x00525B04)
#define g_AnimCommands (*(int16_t **)0x00525B08)
#define g_DrawRoomsArray (*(int16_t(*)[100])0x00525B20)
#define g_AnimBones (*(int32_t **)0x00525BE8)
#define g_DynamicLightCount (*(int32_t*)0x00525BEC)
#define g_StaticObjects (*(STATIC_INFO(*)[50])0x00525C00)
Expand Down
2 changes: 1 addition & 1 deletion src/tr2/inject_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static void M_DecompGeneral(const bool enable)
{
INJECT(enable, 0x00411F50, Game_SetCutsceneTrack);
INJECT(enable, 0x00411F60, Game_Cutscene_Start);
INJECT(enable, 0x00412080, Misc_InitCinematicRooms);
INJECT(enable, 0x00412080, Room_InitCinematic);
INJECT(enable, 0x00412120, Game_Cutscene_Control);
INJECT(enable, 0x004123D0, Room_FindByPos);
INJECT(enable, 0x00412450, CutscenePlayer_Control);
Expand Down

0 comments on commit b06a69f

Please sign in to comment.