KAZIK/src_graphics/steel_door.inc
Artvasil09 51c6512675 feat: implement secret fortune teller room, lived-in den v3, and bar camera stabilization
- Secret Fortune Teller Room: arcade lantern toggle, sliding timber panel, dedicated staircase and compact cellar chamber

- Lived-in den pass v3: cloth hangings, draped workbench, props/clutter, centered entrance, and custom light sources

- Bar camera stabilization: remove alcohol horizon sway while retaining drink animations

- Synchronize binaries and update launcher hash to EADBA9C8C9BD5B7E3CC4CE486ED647C1CE9383D1DCB6EBC94FE755EA1F4BF927
2026-10-20 17:29:52 +03:00

359 lines
8.1 KiB
PHP

; Hysteresis and a hold timer keep the shared doorway safe on both sides.
UpdateBasementDoor3D PROC uses ebx
local nearDoor:DWORD,rangeX:DWORD,rangeY:DWORD
mov nearDoor,0
mov rangeX,FP_1*12/5
mov rangeY,FP_1*7/5
mov eax,basementDoorTarget3D
or eax,basementDoorOpen3D
or eax,basementWheelTime3D
jz @F
mov rangeX,3*FP_1
mov rangeY,FP_1*9/5
@@:
cmp engineMode,MODE_WALK
jne steel_approach_stairs
cmp hallLevel3D,0
jne steel_door_clock
mov eax,playerX
sub eax,FP_1*289/10
cdq
xor eax,edx
sub eax,edx
cmp eax,rangeX
ja steel_door_clock
mov eax,playerY
sub eax,FP_1*105/10
cdq
xor eax,edx
sub eax,edx
cmp eax,rangeY
ja steel_door_clock
jmp steel_request_open
steel_approach_stairs:
cmp engineMode,MODE_STAIRS
jne steel_door_clock
cmp stairRoute3D,1
jne steel_door_clock
mov eax,5*FP_1
cmp rangeX,3*FP_1
jne @F
mov eax,FP_1*13/2
@@:
cmp playerX,eax
ja steel_door_clock
cmp playerY,FP_1*195/10
jb steel_door_clock
cmp playerY,FP_1*235/10
ja steel_door_clock
steel_request_open:
mov nearDoor,1
mov basementDoorTarget3D,FP_1
mov basementDoorHold3D,1200
steel_door_clock:
mov eax,animationClock3D
cmp eax,interiorDoorClock3D
je steel_update_done
mov interiorDoorClock3D,eax
mov ebx,deltaTime3D
cmp ebx,100
jbe @F
mov ebx,100
@@:
cmp nearDoor,1
je steel_animate
; A manual E request outside the automatic opening radius still gets time.
cmp basementDoorTarget3D,FP_1
jne steel_far_hold
cmp basementDoorHold3D,0
jne steel_far_hold
mov eax,basementDoorOpen3D
or eax,basementWheelTime3D
jnz steel_far_hold
mov basementDoorHold3D,2000
steel_far_hold:
cmp basementDoorHold3D,0
je steel_request_close
mov eax,basementDoorHold3D
sub eax,ebx
jae @F
xor eax,eax
@@:
mov basementDoorHold3D,eax
jmp steel_animate
steel_request_close:
mov basementDoorTarget3D,0
steel_animate:
cmp basementDoorTarget3D,0
je steel_close_leaf
cmp basementWheelTime3D,700
jae steel_swing
mov eax,700
sub eax,basementWheelTime3D
cmp ebx,eax
jb steel_wheel_partial
sub ebx,eax
mov basementWheelTime3D,700
jmp steel_swing
steel_wheel_partial:
add basementWheelTime3D,ebx
jmp steel_update_done
steel_swing:
; Opening: unlock first, then swing around the fixed hinge over 1000ms.
imul eax,ebx,FP_1
xor edx,edx
mov ecx,1000
div ecx
add eax,basementDoorOpen3D
cmp eax,FP_1
jbe @F
mov eax,FP_1
@@:
mov basementDoorOpen3D,eax
jmp steel_update_done
steel_close_leaf:
cmp basementDoorOpen3D,0
je steel_lock_wheel
; Carry unused milliseconds into locking only after the leaf is fully shut.
imul eax,basementDoorOpen3D,1000
add eax,FP_1-1
shr eax,16
cmp ebx,eax
jb steel_close_partial
sub ebx,eax
mov basementDoorOpen3D,0
jmp steel_lock_wheel
steel_close_partial:
imul eax,ebx,FP_1
xor edx,edx
mov ecx,1000
div ecx
sub basementDoorOpen3D,eax
jmp steel_update_done
steel_lock_wheel:
mov eax,basementWheelTime3D
sub eax,ebx
jae @F
xor eax,eax
@@:
mov basementWheelTime3D,eax
steel_update_done:
ret
UpdateBasementDoor3D ENDP
; The shared doorway occupies the overlapping landing in both local maps.
StairDoorCanWalk3D PROC px:DWORD,py:DWORD
cmp stairRoute3D,1
jne stair_steel_clear
cmp px,FP_1*35/10
jb stair_steel_clear
cmp px,FP_1*42/10
ja stair_steel_clear
cmp py,FP_1*2025/100
jb stair_steel_blocked
cmp py,FP_1*2175/100
jae stair_steel_blocked
mov eax,px
add eax,25*FP_1
mov edx,py
sub edx,FP_1*21/2
invoke InteriorDoorCanWalk3D,eax,edx
ret
stair_steel_blocked:
xor eax,eax
ret
stair_steel_clear:
mov eax,1
ret
StairDoorCanWalk3D ENDP
RenderStairDoor3D PROC
local oldX:DWORD,oldY:DWORD,oldEye:DWORD
cmp stairRoute3D,1
jne stair_steel_done
; Fill the wider landing around the actual narrow doorway on the stair side.
invoke DrawCityBoxSides3D,FP_1*375/100,4*FP_1,20*FP_1,FP_1*2025/100,FP_1*3/2,FP_1*37/10,92
invoke DrawCityBoxSides3D,FP_1*375/100,4*FP_1,FP_1*2175/100,23*FP_1,FP_1*3/2,FP_1*37/10,92
mov eax,playerX
mov oldX,eax
add playerX,25*FP_1
mov eax,playerY
mov oldY,eax
sub playerY,FP_1*21/2
mov eax,viewEye3D
mov oldEye,eax
sub viewEye3D,FP_1*3/2
invoke DrawCityVertical3D,0,FP_1*2838/100,9*FP_1,12*FP_1,-FP_1/10,FP_1*21/10,131
call DrawBasementLeaf3D
mov eax,oldX
mov playerX,eax
mov eax,oldY
mov playerY,eax
mov eax,oldEye
mov viewEye3D,eax
stair_steel_done:
ret
RenderStairDoor3D ENDP
; Perspective-correct vertical plane with a rotating horizontal basis. The wheel
; is baked into offline texture phases, not rotated in screen space at runtime.
DrawBasementLeaf3D PROC uses ebx esi edi
local ux:DWORD,uy:DWORD,nx:DWORD,ny:DWORD,numerator:DWORD
local depth:DWORD,texture:DWORD,sourceX:DWORD,top:DWORD,bottom:DWORD
local stepY:DWORD,sourceY:DWORD,row:DWORD,column:DWORD,destination:DWORD
invoke ResolveUpperMaterial3D,128
test eax,eax
jz steel_leaf_done
mov texture,eax
mov eax,basementDoorOpen3D
imul eax,128
shr eax,16
and eax,511
mov ecx,tableSin[eax*4]
mov ux,ecx
neg ecx
mov ny,ecx
mov ecx,tableCos[eax*4]
mov uy,ecx
mov nx,ecx
mov eax,FP_1*289/10
sub eax,playerX
imul nx
shrd eax,edx,16
mov ebx,eax
mov eax,FP_1*975/100
sub eax,playerY
imul ny
shrd eax,edx,16
add eax,ebx
mov numerator,eax
mov column,0
steel_leaf_column:
mov ebx,column
mov eax,cityRayX3D[ebx*4]
imul nx
shrd eax,edx,16
mov esi,eax
mov eax,cityRayY3D[ebx*4]
imul ny
shrd eax,edx,16
add eax,esi
mov ecx,eax
cdq
xor eax,edx
sub eax,edx
cmp eax,256
jb steel_leaf_next_column
mov eax,numerator
cdq
shld edx,eax,16
shl eax,16
idiv ecx
cmp eax,4096
jle steel_leaf_next_column
cmp eax,zBuffer[ebx*4]
jae steel_leaf_next_column
cmp portalRendering3D,0
je @F
cmp eax,portalClipDepth3D[ebx*4]
jb steel_leaf_next_column
@@:
mov depth,eax
imul cityRayX3D[ebx*4]
shrd eax,edx,16
add eax,playerX
sub eax,FP_1*289/10
imul ux
shrd eax,edx,16
mov esi,eax
mov eax,depth
imul cityRayY3D[ebx*4]
shrd eax,edx,16
add eax,playerY
sub eax,FP_1*975/100
imul uy
shrd eax,edx,16
add eax,esi
test eax,eax
js steel_leaf_next_column
cmp eax,FP_1*3/2
jae steel_leaf_next_column
imul eax,256
xor edx,edx
mov ecx,FP_1*3/2
div ecx
mov sourceX,eax
mov eax,viewEye3D
sub eax,FP_1*19/10
imul eax,SCREEN_H
cdq
idiv depth
add eax,viewHorizon3D
mov top,eax
mov eax,viewEye3D
imul eax,SCREEN_H
cdq
idiv depth
add eax,viewHorizon3D
mov bottom,eax
sub eax,top
jle steel_leaf_next_column
mov ecx,eax
mov eax,512*FP_1
xor edx,edx
div ecx
mov stepY,eax
mov eax,top
test eax,eax
jns @F
xor eax,eax
@@:
mov row,eax
sub eax,top
imul eax,stepY
mov sourceY,eax
cmp bottom,SCREEN_H
jle @F
mov bottom,SCREEN_H
@@:
mov eax,row
cmp eax,bottom
jge steel_leaf_next_column
imul eax,SCREEN_W
add eax,column
shl eax,2
mov destination,eax
steel_leaf_pixel:
mov edi,destination
mov eax,depth
cmp eax,cityDepthBuffer3D[edi]
ja steel_leaf_next_pixel
mov eax,sourceY
shr eax,16
cmp eax,512
jae steel_leaf_next_pixel
shl eax,8
add eax,sourceX
mov esi,texture
mov eax,[esi+eax*4]
cmp eax,80000000h
jb steel_leaf_next_pixel
and eax,00FFFFFFh
mov screenBuffer[edi],eax
mov eax,depth
mov cityDepthBuffer3D[edi],eax
steel_leaf_next_pixel:
mov eax,stepY
add sourceY,eax
add destination,SCREEN_W*4
inc row
mov eax,row
cmp eax,bottom
jb steel_leaf_pixel
steel_leaf_next_column:
inc column
cmp column,SCREEN_W
jb steel_leaf_column
steel_leaf_done:
ret
DrawBasementLeaf3D ENDP