Skip to content

Commit ffee33d

Browse files
committed
Merge PR #213: Keep the interior camera list at one address
Also resolves #214 and supersedes #216 (same crash, stale-pointer approach).
2 parents 90db632 + 538ebec commit ffee33d

2 files changed

Lines changed: 18 additions & 14 deletions

File tree

‎docs/port/truncations.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ recovered, as `CCharacter::ClothStep` does with `PortImagePointer`) fixes the ro
6161
| site | function | state | class | expression | origin | use |
6262
|---|---|---|---|---|---|---|
6363
| port/src/dataread.cpp:319 | LoadFileBG | port | low-bits | `reinterpret_cast < std :: uintptr_t >(buffer)` | parameter | test |
64-
| port/src/edit_in.cpp:1787 | LoadData | port | low-bits | `reinterpret_cast < std :: intptr_t >(func_point[i].parts)` | field | index: InteriorParts[static_cast < int >(reinterpret_cast < std ... |
64+
| port/src/edit_in.cpp:1791 | LoadData | port | low-bits | `reinterpret_cast < std :: intptr_t >(func_point[i].parts)` | field | index: InteriorParts[static_cast < int >(reinterpret_cast < std ... |
6565
| port/src/texture.cpp:541 | CTextureManager::SetBuffer | port | low-bits | `reinterpret_cast < std :: uintptr_t >(buffer)` | parameter | store: misalignment |
6666
| ps2/src/dataset.cpp:381 | LoadMDSFile | retail | low-bits | `(int)data` | parameter | test |
6767
| ps2/src/gameutil.cpp:290 | MotionProc | retail | low-bits | `(int)list` | parameter | test |

‎port/src/edit_in.cpp‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <libvu0.h>
44

55
#include <algorithm>
6+
#include <array>
67
#include <cmath>
78
#include <cstdint>
89
#include <cstdio>
@@ -146,8 +147,9 @@ namespace {
146147
/** Phase the interior loop is in. */
147148
static int GameMode;
148149

149-
/** Camera marker whose box the player last stood in. */
150-
static INTERIOR_CAMERA *active_camera;
150+
/** Camera marker whose box the player last stood in, by its place in the list SetCameraPos builds each
151+
* frame, or -1 for none. */
152+
static int active_camera = -1;
151153

152154
/** Frames the player may stand outside the active camera marker before the camera switches. */
153155
static int camera_change_count;
@@ -468,7 +470,7 @@ PORT_OVERRIDE int EditInInit(float time, char *name) {
468470
}
469471

470472
EdMoveCharaInit();
471-
active_camera = nullptr;
473+
active_camera = -1;
472474
camera_change_count = 0;
473475
EdIn_MainCamera.FollowOff();
474476
EdIn_NowCamera = &EdIn_MainCamera;
@@ -1410,8 +1412,8 @@ PORT_OVERRIDE void SetCameraPos(CFrame *frame, CCamera *camera, CCharacter *char
14101412
if (camera_capacity == 0) {
14111413
return;
14121414
}
1413-
auto cameras = std::make_unique<INTERIOR_CAMERA[]>(static_cast<std::size_t>(camera_capacity));
1414-
sceVu0FMATRIX matrix;
1415+
std::array<INTERIOR_CAMERA, 8> cameras;
1416+
sceVu0FMATRIX matrix;
14151417
count = 0;
14161418

14171419
for (i = 0; i < func_num; i++, point++) {
@@ -1445,14 +1447,16 @@ PORT_OVERRIDE void SetCameraPos(CFrame *frame, CCamera *camera, CCharacter *char
14451447
return;
14461448
}
14471449

1448-
INTERIOR_CAMERA *inside = nullptr;
1449-
static int cnt = 0;
1450+
// Retail kept the active camera as a pointer into this list from one frame to the next, which only
1451+
// held because its list sat on the stack at the same address every frame; it is kept by its place.
1452+
int inside = -1;
1453+
static int cnt = 0;
14501454

14511455
for (i = 0; i < count; i++) {
14521456
entry = &cameras[i];
14531457

14541458
if (entry->link_id == 0) {
1455-
inside = entry;
1459+
inside = i;
14561460
continue;
14571461
}
14581462

@@ -1461,7 +1465,7 @@ PORT_OVERRIDE void SetCameraPos(CFrame *frame, CCamera *camera, CCharacter *char
14611465
sceVu0ApplyMatrix(local, inverse, position);
14621466

14631467
if (!(local[0] < entry->min[0]) && !(local[1] < entry->min[1]) && !(local[2] < entry->min[2]) && local[0] <= entry->max[0] && local[1] <= entry->max[1] && local[2] <= entry->max[2]) {
1464-
inside = entry;
1468+
inside = i;
14651469
break;
14661470
}
14671471
}
@@ -1472,11 +1476,11 @@ PORT_OVERRIDE void SetCameraPos(CFrame *frame, CCamera *camera, CCharacter *char
14721476
cnt = 0;
14731477
}
14741478

1475-
if (active_camera == nullptr) {
1479+
if (active_camera < 0 || active_camera >= count) {
14761480
active_camera = inside;
14771481
}
14781482

1479-
if (inside == nullptr) {
1483+
if (inside < 0) {
14801484
return;
14811485
}
14821486

@@ -1491,9 +1495,9 @@ PORT_OVERRIDE void SetCameraPos(CFrame *frame, CCamera *camera, CCharacter *char
14911495
camera_change_count--;
14921496
}
14931497

1494-
if (active_camera != nullptr) {
1498+
if (active_camera >= 0) {
14951499
sceVu0FVECTOR eye = {0.0f, 0.0f, 0.0f, 1.0f};
1496-
active_camera->frame.GetWorldPosition(eye, eye);
1500+
cameras[active_camera].frame.GetWorldPosition(eye, eye);
14971501
position[1] += 17.0f;
14981502
camera->SetPos(eye);
14991503
camera->SetRef(position);

0 commit comments

Comments
 (0)