diff --git a/docs/progress.svg b/docs/progress.svg
index bdfc5385..4c5ce4e7 100644
--- a/docs/progress.svg
+++ b/docs/progress.svg
@@ -69,10 +69,10 @@
Tomb2.exe progress according to the physical function order:
-1.92% (23) · 95.67% (1148) · 0.67% (8) · 1.75% (21)
+2% (24) · 95.58% (1147) · 0.67% (8) · 1.75% (21)
-
-
+
+
@@ -209,7 +209,7 @@
void __cdecl Camera_Chase(const struct ITEM_INFO *item);
int32_t __cdecl Camera_ShiftClamp(struct GAME_VECTOR *pos, int32_t clamp);
void __cdecl Camera_Combat(const struct ITEM_INFO *item);
-void __cdecl Camera_Look(struct ITEM_INFO *item);
+void __cdecl Camera_Look(const struct ITEM_INFO *item);
void __cdecl Camera_Fixed(void);
void __cdecl Camera_Update(void);
void __cdecl Camera_SetCutsceneTrack(int32_t track);
@@ -1281,10 +1281,10 @@
Tomb2.exe progress according to the function sizes:
-2.10% · 97.57% · 0.02% · 0.31%
+2.25% · 97.42% · 0.02% · 0.31%
-
-
+
+
@@ -1474,7 +1474,7 @@
void __cdecl LaraWaterCurrent(struct COLL_INFO *coll);
int32_t __cdecl GF_LoadScriptFile(char *fname);
void __cdecl Matrix_RotYXZpack(uint32_t rpack);
-void __cdecl Camera_Look(struct ITEM_INFO *item);
+void __cdecl Camera_Look(const struct ITEM_INFO *item);
void __cdecl EelControl(int16_t item_num);
void __cdecl Matrix_RotYXZ(int16_t ry, int16_t rx, int16_t rz);
void __cdecl MouseControl(int16_t item_num);
diff --git a/docs/progress.txt b/docs/progress.txt
index 7e7dfc9b..436b6210 100644
--- a/docs/progress.txt
+++ b/docs/progress.txt
@@ -985,7 +985,7 @@ typedef struct __unaligned LARA_INFO {
004113F0 000000ED + void __cdecl Camera_Chase(const struct ITEM_INFO *item);
004114E0 0000019E + int32_t __cdecl Camera_ShiftClamp(struct GAME_VECTOR *pos, int32_t clamp);
00411680 0000018E + void __cdecl Camera_Combat(const struct ITEM_INFO *item);
-00411810 000001E2 - void __cdecl Camera_Look(struct ITEM_INFO *item);
+00411810 000001E2 + void __cdecl Camera_Look(const struct ITEM_INFO *item);
00411A00 00000099 - void __cdecl Camera_Fixed(void);
00411AA0 000004A9 * void __cdecl Camera_Update(void);
00411F50 0000000A - void __cdecl Camera_SetCutsceneTrack(int32_t track);
diff --git a/src/game/camera.c b/src/game/camera.c
index c316da0c..ffda1f1d 100644
--- a/src/game/camera.c
+++ b/src/game/camera.c
@@ -550,3 +550,59 @@ void __cdecl Camera_Combat(const struct ITEM_INFO *item)
Camera_SmartShift(&target, Camera_Shift);
Camera_Move(&target, g_Camera.speed);
}
+
+void __cdecl Camera_Look(const struct ITEM_INFO *item)
+{
+ struct PHD_VECTOR old = {
+ .x = g_Camera.target.x,
+ .y = g_Camera.target.y,
+ .z = g_Camera.target.z,
+ };
+
+ g_Camera.target.z = item->pos.z;
+ g_Camera.target.x = item->pos.x;
+ g_Camera.target_angle =
+ item->pos.y_rot + g_Lara.torso_y_rot + g_Lara.head_y_rot;
+ g_Camera.target_distance = LOOK_DISTANCE;
+ g_Camera.target_elevation =
+ g_Lara.torso_x_rot + g_Lara.head_x_rot + item->pos.x_rot;
+
+ int32_t distance =
+ (LOOK_DISTANCE * Math_Cos(g_Camera.target_elevation)) >> W2V_SHIFT;
+
+ g_Camera.shift =
+ (-STEP_L * 2 * Math_Sin(g_Camera.target_elevation)) >> W2V_SHIFT;
+ g_Camera.target.z +=
+ (g_Camera.shift * Math_Cos(item->pos.y_rot)) >> W2V_SHIFT;
+ g_Camera.target.x +=
+ (g_Camera.shift * Math_Sin(item->pos.y_rot)) >> W2V_SHIFT;
+
+ if (!Camera_GoodPosition(
+ g_Camera.target.x, g_Camera.target.y, g_Camera.target.z,
+ g_Camera.target.room_num)) {
+ g_Camera.target.x = item->pos.x;
+ g_Camera.target.z = item->pos.z;
+ }
+
+ g_Camera.target.y += Camera_ShiftClamp(&g_Camera.target, STEP_L + 50);
+
+ const struct PHD_VECTOR offset = {
+ .y =
+ +((g_Camera.target_distance * Math_Sin(g_Camera.target_elevation))
+ >> W2V_SHIFT),
+ .x = -((distance * Math_Sin(g_Camera.target_angle)) >> W2V_SHIFT),
+ .z = -((distance * Math_Cos(g_Camera.target_angle)) >> W2V_SHIFT),
+ };
+
+ struct GAME_VECTOR target = {
+ .x = g_Camera.target.x + offset.x,
+ .y = g_Camera.target.y + offset.y,
+ .z = g_Camera.target.z + offset.z,
+ .room_num = g_Camera.pos.room_num,
+ };
+
+ Camera_SmartShift(&target, Camera_Clip);
+ g_Camera.target.z = old.z + (g_Camera.target.z - old.z) / g_Camera.speed;
+ g_Camera.target.x = old.x + (g_Camera.target.x - old.x) / g_Camera.speed;
+ Camera_Move(&target, g_Camera.speed);
+}
diff --git a/src/game/camera.h b/src/game/camera.h
index 065e6b8a..1fae8b3b 100644
--- a/src/game/camera.h
+++ b/src/game/camera.h
@@ -21,3 +21,4 @@ void __cdecl Camera_SmartShift(
void __cdecl Camera_Chase(const struct ITEM_INFO *item);
int32_t __cdecl Camera_ShiftClamp(struct GAME_VECTOR *pos, int32_t clamp);
void __cdecl Camera_Combat(const struct ITEM_INFO *item);
+void __cdecl Camera_Look(const struct ITEM_INFO *item);
diff --git a/src/global/const.h b/src/global/const.h
index 375fe254..a4acd349 100644
--- a/src/global/const.h
+++ b/src/global/const.h
@@ -17,3 +17,4 @@
#define NO_CAMERA (-1)
#define MAX_ELEVATION (85 * PHD_DEGREE) // = 15470
#define COMBAT_DISTANCE (WALL_L * 5 / 2) // = 2560
+#define LOOK_DISTANCE (WALL_L * 3 / 2) // = 1536
diff --git a/src/global/funcs.h b/src/global/funcs.h
index cf5630e4..8d1b72ba 100644
--- a/src/global/funcs.h
+++ b/src/global/funcs.h
@@ -120,7 +120,6 @@
#define Creature_Vault ((int32_t __cdecl (*)(int16_t item_num, int16_t angle, int32_t vault, int32_t shift))0x00410110)
#define Creature_Kill ((void __cdecl (*)(struct ITEM_INFO *item, int32_t kill_anim, int32_t kill_state, int32_t lara_kill_state))0x00410250)
#define Creature_GetBaddieTarget ((void __cdecl (*)(int16_t item_num, int32_t goody))0x004103C0)
-#define Camera_Look ((void __cdecl (*)(struct ITEM_INFO *item))0x00411810)
#define Camera_Fixed ((void __cdecl (*)(void))0x00411A00)
#define Camera_Update ((void __cdecl (*)(void))0x00411AA0)
#define Camera_SetCutsceneTrack ((void __cdecl (*)(int32_t track))0x00411F50)
diff --git a/src/inject_exec.c b/src/inject_exec.c
index 6a570029..290ad8b9 100644
--- a/src/inject_exec.c
+++ b/src/inject_exec.c
@@ -22,6 +22,7 @@ static void Inject_Camera(void)
INJECT(0x004113F0, Camera_Chase);
INJECT(0x004114E0, Camera_ShiftClamp);
INJECT(0x00411680, Camera_Combat);
+ INJECT(0x00411810, Camera_Look);
}
static void Inject_Matrix(void)