diff --git a/docs/progress.svg b/docs/progress.svg
index 6f0bd840..d37fa2d1 100644
--- a/docs/progress.svg
+++ b/docs/progress.svg
@@ -69,10 +69,10 @@
Tomb2.exe progress according to the physical function order:
-26.08% (313) · 71.42% (857) · 0.67% (8) · 1.83% (22)
+26.17% (314) · 71.33% (856) · 0.67% (8) · 1.83% (22)
-
-
+
+
@@ -655,7 +655,7 @@
int32_t __cdecl Lara_TestWaterStepOut(struct ITEM_INFO *item, struct COLL_INFO *coll);
int32_t __cdecl Lara_TestWaterClimbOut(struct ITEM_INFO *item, struct COLL_INFO *coll);
void __cdecl Lara_HandleUnderwater(struct ITEM_INFO *item, struct COLL_INFO *coll);
-void __cdecl Lara_SwimTurn(struct ITEM_INFO *item);
+void __cdecl Lara_SwimTurn(struct ITEM_INFO *item);
void __cdecl Lara_State_Swim(struct ITEM_INFO *item, struct COLL_INFO *coll);
void __cdecl Lara_State_Glide(struct ITEM_INFO *item, struct COLL_INFO *coll);
void __cdecl Lara_State_Tread(struct ITEM_INFO *item, struct COLL_INFO *coll);
@@ -1281,10 +1281,10 @@
Tomb2.exe progress according to the function sizes:
-22.16% · 77.51% · 0.02% · 0.31%
+22.20% · 77.47% · 0.02% · 0.31%
-
-
+
+
@@ -1886,7 +1886,7 @@
bool __cdecl IntroFMV(LPCTSTR fileName1, LPCTSTR fileName2);
bool __cdecl HideDDrawGameWindow(void);
int32_t __cdecl CreateTexturePalette(RGB888 *pal);
-void __cdecl Lara_SwimTurn(struct ITEM_INFO *item);
+void __cdecl Lara_SwimTurn(struct ITEM_INFO *item);
void __cdecl Sound_UpdateContinued(void);
void __cdecl HookControl(int16_t item_num);
void __cdecl Output_DrawPickup(int32_t sx, int32_t sy, int32_t scale, int16_t sprite_idx, int16_t shade);
diff --git a/docs/progress.txt b/docs/progress.txt
index 190585a4..10698967 100644
--- a/docs/progress.txt
+++ b/docs/progress.txt
@@ -1862,7 +1862,7 @@ typedef enum LARA_MESH {
# game/laraswim.c
00431F50 00000223 + void __cdecl Lara_HandleUnderwater(struct ITEM_INFO *item, struct COLL_INFO *coll);
-00432180 00000086 - void __cdecl Lara_SwimTurn(struct ITEM_INFO *item);
+00432180 00000086 + void __cdecl Lara_SwimTurn(struct ITEM_INFO *item);
00432210 0000006B + void __cdecl Lara_State_Swim(struct ITEM_INFO *item, struct COLL_INFO *coll);
00432280 00000076 + void __cdecl Lara_State_Glide(struct ITEM_INFO *item, struct COLL_INFO *coll);
00432300 00000085 + void __cdecl Lara_State_Tread(struct ITEM_INFO *item, struct COLL_INFO *coll);
diff --git a/src/game/lara/lara_state.c b/src/game/lara/lara_state.c
index 999ecf9a..ee01ef51 100644
--- a/src/game/lara/lara_state.c
+++ b/src/game/lara/lara_state.c
@@ -9,6 +9,25 @@
#include "global/vars.h"
#include "util.h"
+void __cdecl Lara_SwimTurn(struct ITEM_INFO *const item)
+{
+ if (g_Input & IN_FORWARD) {
+ item->pos.x_rot -= LARA_TURN_RATE_UW;
+ } else if (g_Input & IN_BACK) {
+ item->pos.x_rot += LARA_TURN_RATE_UW;
+ }
+
+ if (g_Input & IN_LEFT) {
+ g_Lara.turn_rate -= LARA_TURN_RATE;
+ CLAMPL(g_Lara.turn_rate, -LARA_MED_TURN);
+ item->pos.z_rot -= LARA_LEAN_RATE_SWIM;
+ } else if (g_Input & IN_RIGHT) {
+ g_Lara.turn_rate += LARA_TURN_RATE;
+ CLAMPG(g_Lara.turn_rate, LARA_MED_TURN);
+ item->pos.z_rot += LARA_LEAN_RATE_SWIM;
+ }
+}
+
void __cdecl Lara_State_Walk(struct ITEM_INFO *item, struct COLL_INFO *coll)
{
if (item->hit_points <= 0) {
diff --git a/src/game/lara/lara_state.h b/src/game/lara/lara_state.h
index efde4853..70a39ef0 100644
--- a/src/game/lara/lara_state.h
+++ b/src/game/lara/lara_state.h
@@ -4,6 +4,9 @@
#include "global/types.h"
+// TODO: make static
+void __cdecl Lara_SwimTurn(struct ITEM_INFO *const item);
+
void __cdecl Lara_State_Walk(struct ITEM_INFO *item, struct COLL_INFO *coll);
void __cdecl Lara_State_Run(struct ITEM_INFO *item, struct COLL_INFO *coll);
void __cdecl Lara_State_Stop(struct ITEM_INFO *item, struct COLL_INFO *coll);
diff --git a/src/global/const.h b/src/global/const.h
index 0da6c706..ccb1ad43 100644
--- a/src/global/const.h
+++ b/src/global/const.h
@@ -49,6 +49,7 @@
#define FAST_FALL_SPEED 128
#define LARA_TURN_UNDO (2 * PHD_DEGREE) // = 364
#define LARA_TURN_RATE ((PHD_DEGREE / 4) + LARA_TURN_UNDO) // = 409
+#define LARA_TURN_RATE_UW (2 * PHD_DEGREE) // = 364
#define LARA_MED_TURN ((PHD_DEGREE * 4) + LARA_TURN_UNDO) // = 1092
#define LARA_SLOW_TURN ((PHD_DEGREE * 2) + LARA_TURN_UNDO) // = 728
#define LARA_SURF_TURN (LARA_SLOW_TURN / 2) // = 364
@@ -57,6 +58,7 @@
#define LARA_LEAN_UNDO_SURF (LARA_LEAN_UNDO * 2) // = 364
#define LARA_LEAN_UNDO_UW LARA_LEAN_UNDO_SURF // = 364
#define LARA_LEAN_RATE 273
+#define LARA_LEAN_RATE_SWIM (LARA_LEAN_RATE * 2) // = 546
#define LARA_LEAN_MAX ((10 * PHD_DEGREE) + LARA_LEAN_UNDO) // = 2002
#define LARA_LEAN_MAX_UW (LARA_LEAN_MAX * 2) // = 4004
#define LARA_JUMP_TURN ((PHD_DEGREE * 1) + LARA_TURN_UNDO) // = 546
diff --git a/src/global/funcs.h b/src/global/funcs.h
index 1dcb2e36..cd0df27e 100644
--- a/src/global/funcs.h
+++ b/src/global/funcs.h
@@ -349,7 +349,6 @@
#define Lara_SurfaceCollision ((void __cdecl (*)(struct ITEM_INFO *item, struct COLL_INFO *coll))0x00431B40)
#define Lara_TestWaterStepOut ((int32_t __cdecl (*)(struct ITEM_INFO *item, struct COLL_INFO *coll))0x00431C40)
#define Lara_TestWaterClimbOut ((int32_t __cdecl (*)(struct ITEM_INFO *item, struct COLL_INFO *coll))0x00431D30)
-#define Lara_SwimTurn ((void __cdecl (*)(struct ITEM_INFO *item))0x00432180)
#define Lara_GetWaterDepth ((int32_t __cdecl (*)(int32_t x, int32_t y, int32_t z, int16_t room_num))0x004324A0)
#define Lara_TestWaterDepth ((void __cdecl (*)(struct ITEM_INFO *item, struct COLL_INFO *coll))0x00432640)
#define Lara_SwimCollision ((void __cdecl (*)(struct ITEM_INFO *item, struct COLL_INFO *coll))0x00432710)