; ============================================================================== ; 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 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 ; 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 invoke IsSolidCell, eax test eax, eax jnz skip_x_move ; Collision on X: slide along wall! 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 invoke IsSolidCell, eax test eax, eax jnz update_player_done ; Collision on Y mov eax, nextY mov playerY, eax update_player_done: ret UpdatePlayer ENDP