EBLAN_ENGINE/include/engine_physics.inc
Artvasil09 a1d1baa869 feat: complete engine and editor subsystems (Stages 1-5 from TODO_ARTEM)
- Stage 1: Eliminate fish-eye distortion with precomputed tangential ray offset table and fractional DDA depth
- Stage 2: Full asset management in EblanStudio (stb_image/stb_image_write, 128x128 BGRA texture packaging, WAV sound manager)
- Stage 3: Multi-level room streaming, LevelTransition/CELL_PORTAL trigger system, 16-frame screen fade to black
- Stage 4: 60Hz cutscene engine in pure x86 ASM (v4 binary track, waypoint camera motion, shortest-arc pan, CP1251 Russian subtitles, letterbox overlay, audio)
- Stage 5: EblanStudio cutscene timeline (F6) and windowless Live ASM Viewport over shared-memory IPC directly rendered into DX11
- Tooling & Tests: comprehensive regression test suite (94 editor + 107 engine tests), IPC tests, and cutscene demo
2026-10-22 16:24:22 +03:00

228 lines
5 KiB
PHP

; ==============================================================================
; EBLAN ENGINE - Player Movement, Physics & Collision Handling
; ==============================================================================
.code
; ------------------------------------------------------------------------------
; UpdatePlayer: Updates rotation, computes movement vector & handles collisions
; ------------------------------------------------------------------------------
UpdatePlayer PROC uses ebx ecx edx esi edi
LOCAL moveX:DWORD, moveY:DWORD
LOCAL speed:DWORD
LOCAL nextX:DWORD, nextY:DWORD
LOCAL checkGridX:DWORD, checkGridY:DWORD
; Freeze player movement and inputs during level transitions
cmp fadeState, 0
jne update_player_done
cmp cutscenePending, 0
je scene_manual_start
call StartCutscene
scene_manual_start:
cmp keyCutscene, 0
je scene_check_active
cmp isCutsceneActive, 0
jne scene_check_active
call StartCutscene
scene_check_active:
cmp isCutsceneActive, 0
je normal_player_update
cmp keySkipScene, 0
je scene_update_tick
call StopCutscene
ret
scene_update_tick:
call UpdateCutscene
ret
normal_player_update:
mov moveX, 0
mov moveY, 0
; 1. Handle Camera Rotation
cmp keyTurnLeft, 0
je check_turn_right
mov eax, playerAngle
sub eax, playerTurnSpeed
and eax, ANGLE_MASK
mov playerAngle, eax
check_turn_right:
cmp keyTurnRight, 0
je check_action
mov eax, playerAngle
add eax, playerTurnSpeed
and eax, ANGLE_MASK
mov playerAngle, eax
check_action:
cmp keyAction, 0
je check_movement
call InteractDoor
cmp fadeState, 0
jne update_player_done
; 2. Determine Movement Speed
check_movement:
mov eax, playerMoveSpeed ; Base speed: raw units/frame
cmp keyRun, 0
je @F
mov eax, playerRunSpeed ; Sprint speed
@@:
mov speed, eax
; 3. Forward / Backward Vector
cmp keyForward, 0
je check_backward
mov eax, playerAngle
and eax, ANGLE_MASK
; dx += cos(angle) * speed
mov ebx, [tableCos + eax*4]
imul ebx, speed
sar ebx, 16
add moveX, ebx
; dy += sin(angle) * speed
mov ecx, [tableSin + eax*4]
imul ecx, speed
sar ecx, 16
add moveY, ecx
check_backward:
cmp keyBackward, 0
je check_strafe_left
mov eax, playerAngle
and eax, ANGLE_MASK
mov ebx, [tableCos + eax*4]
imul ebx, speed
sar ebx, 16
sub moveX, ebx
mov ecx, [tableSin + eax*4]
imul ecx, speed
sar ecx, 16
sub moveY, ecx
; 4. Strafe Left / Right Vector (Angle +/- 90 degrees)
check_strafe_left:
cmp keyStrafeLeft, 0
je check_strafe_right
; Left vector is (angle - 128)
mov eax, playerAngle
sub eax, ANGLE_90
and eax, ANGLE_MASK
mov ebx, [tableCos + eax*4]
imul ebx, speed
sar ebx, 16
add moveX, ebx
mov ecx, [tableSin + eax*4]
imul ecx, speed
sar ecx, 16
add moveY, ecx
check_strafe_right:
cmp keyStrafeRight, 0
je apply_physics
; Right vector is (angle + 128)
mov eax, playerAngle
add eax, ANGLE_90
and eax, ANGLE_MASK
mov ebx, [tableCos + eax*4]
imul ebx, speed
sar ebx, 16
add moveX, ebx
mov ecx, [tableSin + eax*4]
imul ecx, speed
sar ecx, 16
add moveY, ecx
; 5. Apply Movement with Wall-Sliding Collision Detection
apply_physics:
mov eax, moveX
or eax, moveY
jz update_player_done ; No movement input
; --- Test X Movement ---
mov eax, playerX
add eax, moveX
mov nextX, eax
; Buffer check (collision body radius)
mov ebx, nextX
cmp moveX, 0
jge @F
mov eax, playerRadius
sub ebx, eax ; Moving left: check left edge
jmp check_x_col
@@:
mov eax, playerRadius
add ebx, eax ; Moving right: check right edge
check_x_col:
sar ebx, 6 ; divide by CELL_SIZE (64)
mov checkGridX, ebx
mov ecx, playerY
sar ecx, 6
mov checkGridY, ecx
invoke GetMapCell, checkGridX, checkGridY
cmp eax, CELL_PORTAL
je allow_portal_x
invoke IsSolidCell, eax
test eax, eax
jnz skip_x_move ; Collision on X: slide along wall!
allow_portal_x:
mov eax, nextX
mov playerX, eax
skip_x_move:
; --- Test Y Movement ---
mov eax, playerY
add eax, moveY
mov nextY, eax
mov ecx, nextY
cmp moveY, 0
jge @F
mov eax, playerRadius
sub ecx, eax
jmp check_y_col
@@:
mov eax, playerRadius
add ecx, eax
check_y_col:
sar ecx, 6
mov checkGridY, ecx
mov ebx, playerX
sar ebx, 6
mov checkGridX, ebx
invoke GetMapCell, checkGridX, checkGridY
cmp eax, CELL_PORTAL
je allow_portal_y
invoke IsSolidCell, eax
test eax, eax
jnz update_player_done ; Collision on Y
allow_portal_y:
mov eax, nextY
mov playerY, eax
update_player_done:
cmp fadeState, 0
jne @F
call CheckPortalTriggers
@@:
ret
UpdatePlayer ENDP