diff --git a/docs/progress.svg b/docs/progress.svg
index eaebe526d..e914a977c 100644
--- a/docs/progress.svg
+++ b/docs/progress.svg
@@ -69,8 +69,8 @@
-
-
+
+
@@ -100,7 +100,7 @@
-
+
@@ -149,9 +149,9 @@
-
+
-
+
@@ -169,9 +169,9 @@
-
+
-
+
@@ -179,11 +179,11 @@
-
+
-
-
-
+
+
+
@@ -199,13 +199,13 @@
-
-
+
+
-
+
-
-
+
+
@@ -223,28 +223,28 @@
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
@@ -253,36 +253,36 @@
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
@@ -318,15 +318,15 @@
-
+
-
+
-
-
-
+
+
+
@@ -420,14 +420,14 @@
-
-
-
+
+
+
-
-
-
+
+
+
@@ -445,23 +445,23 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
@@ -496,7 +496,7 @@
-
+
@@ -511,9 +511,9 @@
-
-
-
+
+
+
@@ -528,8 +528,8 @@
-
-
+
+
@@ -560,84 +560,84 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -655,12 +655,12 @@
-
-
-
+
+
+
-
+
@@ -674,739 +674,795 @@
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TombATI functions, arranged according to the function sizes:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Functions decompiled (count): 26.53%
-Functions decompiled (bytesize): 21.26%
-Functions not decompiled, but with known names (count): 58.35%
-Functions not decompiled, but with known names (bytesize): 61.64%
-Functions not decompiled, with unknown names (count): 15.12%
-Functions not decompiled, with unknown names (bytesize): 17.10%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Functions decompiled (count): 25.51%
+Functions decompiled (bytesize): 20.85%
+Functions not decompiled, but with known names (count): 59.26%
+Functions not decompiled, but with known names (bytesize): 61.93%
+Functions not decompiled, with unknown names (count): 15.23%
+Functions not decompiled, with unknown names (bytesize): 17.22%
diff --git a/docs/progress.txt b/docs/progress.txt
index c0caa2b50..f4c430a1c 100644
--- a/docs/progress.txt
+++ b/docs/progress.txt
@@ -71,6 +71,7 @@ sub_408323 0x00408323 0x00000029 -
sub_40834C 0x0040834C 0x0000001C -
sub_408368 0x00408368 0x00000017 -
sub_40837F 0x0040837F 0x0000008A -
+sub_408409 0x00408409 0x000000D5 -
sub_4084DE 0x004084DE 0x0000030C -
sub_4087EA 0x004087EA 0x0000020A -
SwitchResolution 0x004089F4 0x0000007C -
@@ -136,6 +137,7 @@ DoCinematic 0x00411240 0x0000012B -
CalculateCinematicCamera 0x00411370 0x00000124 -
ControlCinematicPlayer 0x004114A0 0x00000045 -
InitialisePlayer1 0x004114F0 0x000000CD -
+InitialiseGenPlayer 0x004115C0 0x00000027 -
InGameCinematicCamera 0x004115F0 0x00000190 -
GetCollisionInfo 0x00411780 0x000007DD *
CollideStaticObjects 0x00411FA0 0x000003D6 -
@@ -220,7 +222,9 @@ ItemSparkle 0x0041A550 0x00000115 *
FxLaraBubbles 0x0041A670 0x000000E8 -
ControlBubble1 0x0041A760 0x000000FF -
Splash 0x0041A860 0x000000CD *
+ControlSplash1 0x0041A930 0x0000007A -
ControlWaterFall 0x0041A9B0 0x00000120 -
+FxFinishLevel 0x0041AAD0 0x0000000B -
FxTurn180 0x0041AAE0 0x0000000B -
FxDinoStomp 0x0041AAF0 0x00000096 -
FxLaraNormal 0x0041AB90 0x00000035 -
@@ -298,6 +302,7 @@ Inv_RequestItem 0x00421200 0x00000077 *
Inv_RemoveAllItems 0x00421280 0x0000001E *
Inv_RemoveItem 0x004212A0 0x00000110 *
Inv_GetItemOption 0x004213B0 0x000000A7 -
+RemoveInventoryText 0x00421550 0x00000028 -
Inv_RingInit 0x00421580 0x0000017E -
Inv_RingGetView 0x00421700 0x00000060 -
Inv_RingLight 0x00421760 0x00000040 -
@@ -451,8 +456,11 @@ LaraSwimCollision 0x00429340 0x000000FA +
LaraWaterCurrent 0x00429440 0x000001DB +
DrawLightning 0x00429620 0x000004D1 -
InitialiseLightning 0x00429B00 0x0000007E -
+LightningControl 0x00429B80 0x000002AF -
+LightningCollision 0x00429E30 0x00000061 -
InitialiseThorsHandle 0x00429EA0 0x00000086 -
ThorsHandleControl 0x00429F30 0x000002B0 -
+ThorsHandleCollision 0x0042A1F0 0x0000004B -
ThorsHeadCollision 0x0042A240 0x00000052 -
sub_42A2A0 0x0042A2A0 0x0000000C -
sub_42A2B0 0x0042A2B0 0x0000000C -
@@ -482,20 +490,29 @@ MovableBlockControl 0x0042B460 0x0000014A -
MovableBlockCollision 0x0042B5B0 0x00000208 -
TestBlockPush 0x0042B7E0 0x00000142 -
TestBlockPull 0x0042B940 0x00000239 -
+InitialiseRollingBlock 0x0042BB90 0x00000024 -
RollingBlockControl 0x0042BBC0 0x000000DA -
AlterFloorHeight 0x0042BCA0 0x000000BE -
+DrawMovableBlock 0x0042BD60 0x00000081 -
DrawUnclippedItem 0x0042BDF0 0x00000068 *
AbortionControl 0x0042BE60 0x0000049E *
NatlaControl 0x0042C330 0x0000059F *
ControlNatlaGun 0x0042C910 0x00000121 -
InitialiseDoor 0x0042CA40 0x000004AE -
+DoorControl 0x0042CEF0 0x0000023B -
OnDrawBridge 0x0042D130 0x000000B1 -
DrawBridgeFloor 0x0042D1F0 0x0000003B -
DrawBridgeCeiling 0x0042D230 0x0000003F -
+DrawBridgeCollision 0x0042D270 0x0000002F -
+BridgeFlatFloor 0x0042D2A0 0x00000019 -
BridgeFlatCeiling 0x0042D2C0 0x0000001E -
+BridgeTilt1Floor 0x0042D2E0 0x00000048 -
BridgeTilt1Ceiling 0x0042D330 0x0000004D -
+BridgeTilt2Floor 0x0042D380 0x00000047 -
BridgeTilt2Ceiling 0x0042D3D0 0x0000004C -
+CogControl 0x0042D420 0x00000075 -
CabinControl 0x0042D4A0 0x0000007F -
+BoatControl 0x0042D520 0x0000005B -
Scion3Control 0x0042D580 0x00000176 -
EarthQuakeControl 0x0042D700 0x0000006F -
do_inventory_options 0x0042D770 0x00000180 -
@@ -543,6 +560,7 @@ PickUpScionCollision 0x00433240 0x00000164 -
PickUpScion4Collision 0x004333B0 0x00000108 -
MidasCollision 0x004334C0 0x00000217 -
SwitchCollision 0x004336F0 0x0000011C -
+SwitchCollision2 0x00433810 0x000000F0 -
KeyHoleCollision 0x00433900 0x00000227 -
PuzzleHoleCollision 0x00433B40 0x00000277 -
SwitchControl 0x00433DE0 0x0000003D -
@@ -626,7 +644,9 @@ T_DrawText 0x00439B00 0x00000153 +
T_DrawThisText 0x00439C60 0x000003A2 +
InitialiseRollingBall 0x0043A010 0x00000040 -
RollingBallControl 0x0043A050 0x0000025D -
+RollingBallCollision 0x0043A2B0 0x00000264 -
SpikeCollision 0x0043A520 0x0000014E -
+TrapDoorControl 0x0043A670 0x00000053 -
TrapDoorFloor 0x0043A6D0 0x00000042 -
TrapDoorCeiling 0x0043A720 0x00000046 -
OnTrapDoor 0x0043A770 0x000000A3 -
@@ -636,11 +656,13 @@ FallingBlockFloor 0x0043AA70 0x00000035 -
FallingBlockCeiling 0x0043AAB0 0x00000034 -
TeethTrapControl 0x0043AAF0 0x000000C1 -
FallingCeilingControl 0x0043ABC0 0x0000009E -
+InitialiseDamoclesSword 0x0043AC60 0x0000003E -
DamoclesSwordControl 0x0043ACA0 0x00000129 -
DamoclesSwordCollision 0x0043ADD0 0x000000E8 -
DartEmitterControl 0x0043AEC0 0x0000019B -
DartsControl 0x0043B060 0x00000140 -
DartEffectControl 0x0043B1A0 0x0000004C -
+FlameEmitterControl 0x0043B1F0 0x000000A3 -
FlameControl 0x0043B2A0 0x00000185 -
LavaBurn 0x0043B430 0x000000E8 -
LavaEmitterControl 0x0043B520 0x000000C7 -
@@ -650,6 +672,7 @@ CentaurControl 0x0043B850 0x000002B9 *
InitialiseWarrior2 0x0043BB30 0x00000028 *
FlyerControl 0x0043BB60 0x00000625 *
ControlMissile 0x0043C1C0 0x0000026D -
+ShardGun 0x0043C430 0x00000110 -
RocketGun 0x0043C540 0x00000110 -
InitialiseMummy 0x0043C650 0x0000003A *
MummyControl 0x0043C690 0x000000A0 *
@@ -670,6 +693,10 @@ WndProc 0x0043DE00 0x0000011F -
InitialiseWolf 0x0043DF20 0x00000024 *
WolfControl 0x0043DF50 0x0000040B *
LionControl 0x0043E390 0x000002BD *
+sub_43E670 0x0043E670 0x00000011 -
+sub_43E681 0x0043E681 0x000000CC -
+sub_43E74D 0x0043E74D 0x0000015F -
+sub_43E8AC 0x0043E8AC 0x00000155 -
phd_PushMatrix 0x0043EA01 0x00000020 -
phd_PushUnitMatrix 0x0043EA21 0x00000035 *
flatA 0x0043EA80 0x00000064 -
@@ -704,4 +731,5 @@ sub_450870 0x00450870 0x00000006 -
sub_450880 0x00450880 0x00000013 -
sub_4508A0 0x004508A0 0x00000013 -
sub_4508C0 0x004508C0 0x00000056 -
+RtlUnwind 0x00450916 0x00000006 -
WriteTombAtiSettings 0x0045A084 0x00000090 -
diff --git a/docs/update_function_names b/docs/update_function_names
deleted file mode 100755
index 353c00965..000000000
--- a/docs/update_function_names
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/python3
-import sys
-import re
-import typing as T
-from dataclasses import dataclass
-from pathlib import Path
-
-
-DOCS_DIR = Path(__file__).parent
-PROGRESS_TXT_FILE = DOCS_DIR / "progress.txt"
-
-
-@dataclass
-class IdaFunction:
- name: str
- offset: int
-
-
-def collect_ida_functions() -> T.Iterable[IdaFunction]:
- for line in sys.stdin:
- line = line.strip()
- if not line.startswith("#") and line:
- name, _section, offset_str, *_unused = re.split(r"\s+", line)
- yield IdaFunction(name=name, offset=int(offset_str, 16))
-
-
-def update_function_names(ida_functions: T.Iterable[IdaFunction]) -> int:
- ida_func_map = {func.offset: func for func in ida_functions}
- updated = 0
- lines = []
- for line in PROGRESS_TXT_FILE.open("r", encoding="utf-8"):
- line = line.strip()
- if not line.startswith("#") and line:
- name, offset_str, size_str, flags = re.split(r"\s+", line)
- offset = int(offset_str, 16)
- size = int(size_str, 16)
- ida_func = ida_func_map.get(offset)
- if ida_func and ida_func.name!= name:
- name = ida_func.name
- line = re.sub(r"^\w+\s+", "%-31s " % name, line)
- updated += 1
- lines.append(line)
- new_text = "\n".join(lines) + "\n"
- if new_text != PROGRESS_TXT_FILE.read_text():
- PROGRESS_TXT_FILE.write_text(new_text)
- return updated
-
-
-def main() -> None:
- ida_functions = list(collect_ida_functions())
- updated = update_function_names(ida_functions)
- print(updated, 'names updated')
-
-
-if __name__ == "__main__":
- main()
diff --git a/docs/update_functions b/docs/update_functions
new file mode 100755
index 000000000..e3a89310e
--- /dev/null
+++ b/docs/update_functions
@@ -0,0 +1,139 @@
+#!/usr/bin/python3
+import sys
+import re
+import typing as T
+from dataclasses import dataclass
+from pathlib import Path
+
+
+DOCS_DIR = Path(__file__).parent
+PROGRESS_TXT_FILE = DOCS_DIR / "progress.txt"
+
+
+@dataclass
+class IdaFunction:
+ name: str
+ offset: int
+ size: int
+ flags: str
+
+
+class BaseProgressLine:
+ def to_progress_line() -> str:
+ raise NotImplementedError("not implemented")
+
+
+@dataclass
+class MyFunction(BaseProgressLine):
+ name: str
+ offset: int
+ size: int
+ flags: str
+
+ def to_progress_line(self) -> str:
+ return f"{self.name:31s} 0x{self.offset:08X} 0x{self.size:08X} {self.flags}"
+
+
+@dataclass
+class MyComment(BaseProgressLine):
+ text: str
+
+ def to_progress_line(self) -> str:
+ return self.text
+
+
+def collect_ida_functions() -> T.Iterable[IdaFunction]:
+ for line in sys.stdin:
+ line = line.strip()
+ if not line.startswith("#") and line:
+ (
+ name,
+ _section,
+ offset_str,
+ size_str,
+ _locals,
+ _arguments,
+ flags,
+ ) = re.split(r"\s+", line, maxsplit=6)
+ flags = re.sub(r"\s+", "", flags)
+ if "L" not in flags:
+ yield IdaFunction(
+ name=name,
+ offset=int(offset_str, 16),
+ size=int(size_str, 16),
+ flags=flags,
+ )
+
+
+def collect_my_functions() -> T.Iterable[BaseProgressLine]:
+ for line in PROGRESS_TXT_FILE.open("r", encoding="utf-8"):
+ line = line.strip()
+ if line.startswith("#") or not line:
+ yield MyComment(text=line)
+ continue
+
+ name, offset_str, size_str, flags = re.split(r"\s+", line)
+ yield MyFunction(
+ name=name,
+ offset=int(offset_str, 16),
+ size=int(size_str, 16),
+ flags=flags,
+ )
+
+
+def update_functions(
+ ida_functions: T.Iterable[IdaFunction],
+ my_functions: T.Iterable[BaseProgressLine],
+) -> int:
+ results = list(my_functions)
+
+ # update names
+ ida_func_map = {func.offset: func for func in ida_functions}
+ for my_function in results:
+ if isinstance(my_function, MyFunction):
+ ida_func = ida_func_map.get(my_function.offset)
+ if ida_func and ida_func.name != my_function.name:
+ my_function.name = ida_func.name
+
+ # insert missing functions
+ my_func_map = {
+ func.offset: i
+ for i, func in enumerate(results)
+ if isinstance(func, MyFunction)
+ }
+ last_i = -1
+ for ida_function in reversed(ida_functions):
+ if ida_function.offset not in my_func_map:
+ results.insert(
+ last_i,
+ MyFunction(
+ name=ida_function.name,
+ offset=ida_function.offset,
+ size=ida_function.size,
+ flags="-",
+ ),
+ )
+ else:
+ last_i = my_func_map[ida_function.offset]
+
+ return results
+
+
+def main() -> None:
+ ida_functions = list(collect_ida_functions())
+ my_functions = list(collect_my_functions())
+ updated_functions = list(update_functions(ida_functions, my_functions))
+
+ new_text = (
+ "\n".join(
+ function.to_progress_line() for function in updated_functions
+ )
+ + "\n"
+ )
+ if new_text != PROGRESS_TXT_FILE.read_text():
+ PROGRESS_TXT_FILE.write_text(new_text)
+ print("changed")
+
+
+if __name__ == "__main__":
+ main()