KAZIK/src_graphics/interior_portals.inc

267 lines
7.3 KiB
PHP

; Doorways show the adjacent native scene through a depth-tested screen-space
; aperture. Camera translations are the same as the walking thresholds.
DrawInteriorView3D PROC uses ebx esi edi axis:DWORD,plane:DWORD,lo:DWORD,hi:DWORD,z0:DWORD,z1:DWORD,offsetX:DWORD,offsetY:DWORD,offsetZ:DWORD,targetMap:DWORD,targetMode:DWORD,targetLevel:DWORD,targetFloor:DWORD,targetRoute:DWORD
local oldX:DWORD,oldY:DWORD,oldEye:DWORD,oldCeiling:DWORD,oldMap:DWORD
local oldMode:DWORD,oldLevel:DWORD,oldFloor:DWORD,oldRoute:DWORD
local found:DWORD,depth:DWORD,row:DWORD,pixel:DWORD
mov found,0
xor ebx,ebx
portal_mask_column:
mov portalClipDepth3D[ebx*4],0
cmp axis,0
jne portal_mask_y
invoke CityRayPlane3D,plane,playerX,cityRayX3D[ebx*4]
jmp portal_mask_depth
portal_mask_y:
invoke CityRayPlane3D,plane,playerY,cityRayY3D[ebx*4]
portal_mask_depth:
cmp eax,2048
jle portal_mask_next
; The aperture is visible throughout the room, not just within eight metres.
cmp eax,64*FP_1
ja portal_mask_next
cmp eax,zBuffer[ebx*4]
ja portal_mask_next
mov depth,eax
cmp axis,0
jne portal_along_x
imul cityRayY3D[ebx*4]
shrd eax,edx,16
add eax,playerY
jmp portal_mask_along
portal_along_x:
imul cityRayX3D[ebx*4]
shrd eax,edx,16
add eax,playerX
portal_mask_along:
cmp eax,lo
jl portal_mask_next
cmp eax,hi
jge portal_mask_next
mov eax,viewEye3D
sub eax,z1
imul eax,SCREEN_H
cdq
idiv depth
add eax,viewHorizon3D
test eax,eax
jns @F
xor eax,eax
@@:
mov portalClipTop3D[ebx*4],eax
mov eax,viewEye3D
sub eax,z0
imul eax,SCREEN_H
cdq
idiv depth
add eax,viewHorizon3D
cmp eax,SCREEN_H
jle @F
mov eax,SCREEN_H
@@:
cmp eax,portalClipTop3D[ebx*4]
jle portal_mask_next
mov portalClipBottom3D[ebx*4],eax
mov eax,depth
mov portalClipDepth3D[ebx*4],eax
inc found
portal_mask_next:
inc ebx
cmp ebx,SCREEN_W
jb portal_mask_column
cmp found,0
je portal_view_done
cld
lea esi,screenBuffer
lea edi,portalSourcePixels3D
mov ecx,SCREEN_SIZE
rep movsd
lea esi,cityDepthBuffer3D
lea edi,portalSourceDepth3D
mov ecx,SCREEN_SIZE
rep movsd
lea esi,zBuffer
lea edi,portalSourceWalls3D
mov ecx,SCREEN_W
rep movsd
mov eax,playerX
mov oldX,eax
add eax,offsetX
mov playerX,eax
mov eax,playerY
mov oldY,eax
add eax,offsetY
mov playerY,eax
mov eax,viewEye3D
mov oldEye,eax
add eax,offsetZ
mov viewEye3D,eax
mov eax,viewCeiling3D
mov oldCeiling,eax
mov viewCeiling3D,FP_1*5/2
cmp targetMode,MODE_STAIRS
jne @F
mov viewCeiling3D,FP_1*11/2
cmp targetRoute,3
jne @F
mov viewCeiling3D,4*FP_1
@@:
mov eax,worldMap3D
mov oldMap,eax
mov eax,targetMap
mov worldMap3D,eax
mov eax,engineMode
mov oldMode,eax
mov eax,targetMode
mov engineMode,eax
mov eax,hallLevel3D
mov oldLevel,eax
mov eax,targetLevel
mov hallLevel3D,eax
cmp eax,HALL_BOWLING
jne @F
mov viewCeiling3D,6*FP_1
@@:
mov eax,floorTexture3D
mov oldFloor,eax
mov eax,targetFloor
mov floorTexture3D,eax
mov eax,stairRoute3D
mov oldRoute,eax
mov eax,targetRoute
mov stairRoute3D,eax
mov portalRendering3D,1
call UpdateCamera3D
cmp targetLevel,HALL_BOWLING
je portal_target_world_ready
call RenderCeilingAndFloor
call RenderWalls
call PrepareCityDepth3D
call RenderSprites
portal_target_world_ready:
call RenderHall3D
mov portalRendering3D,0
mov eax,oldX
mov playerX,eax
mov eax,oldY
mov playerY,eax
mov eax,oldEye
mov viewEye3D,eax
mov eax,oldCeiling
mov viewCeiling3D,eax
mov eax,oldMap
mov worldMap3D,eax
mov eax,oldMode
mov engineMode,eax
mov eax,oldLevel
mov hallLevel3D,eax
mov eax,oldFloor
mov floorTexture3D,eax
mov eax,oldRoute
mov stairRoute3D,eax
mov row,0
xor edi,edi
portal_compose_row:
xor ebx,ebx
portal_compose_pixel:
mov eax,portalClipDepth3D[ebx*4]
test eax,eax
jz portal_restore_pixel
mov ecx,row
cmp ecx,portalClipTop3D[ebx*4]
jl portal_restore_pixel
cmp ecx,portalClipBottom3D[ebx*4]
jge portal_restore_pixel
cmp eax,portalSourceDepth3D[edi]
ja portal_restore_pixel
; The rendered destination is already in screenBuffer at this exact ray.
; Keep destination depth, so the hinged leaf can occlude the continuation.
inc portalPixelsWritten3D
jmp portal_compose_next
portal_restore_pixel:
mov eax,portalSourcePixels3D[edi]
mov screenBuffer[edi],eax
mov eax,portalSourceDepth3D[edi]
mov cityDepthBuffer3D[edi],eax
portal_compose_next:
add edi,4
inc ebx
cmp ebx,SCREEN_W
jb portal_compose_pixel
inc row
cmp row,SCREEN_H
jb portal_compose_row
lea esi,portalSourceWalls3D
lea edi,zBuffer
mov ecx,SCREEN_W
rep movsd
call UpdateCamera3D
call PrepareCityRays3D
portal_view_done:
ret
DrawInteriorView3D ENDP
RenderInteriorViews3D PROC
cmp portalRendering3D,0
jne interior_views_done
mov portalPixelsWritten3D,0
cmp hallLevel3D,0
jne @F
call RenderBowlingEntrance3D
@@:
cmp hallLevel3D,3
je RenderFortuneViews3D
cmp engineMode,MODE_STAIRS
jne @F
cmp stairRoute3D,3
je RenderFortuneViews3D
@@:
cmp engineMode,MODE_STAIRS
je interior_views_stairs
cmp hallLevel3D,2
je interior_views_lounge
cmp hallLevel3D,1
je interior_views_bunker
call RenderFortuneViews3D
cmp playerX,FP_1*303/10
jae @F
invoke DrawInteriorView3D,0,FP_1*3025/100,20*FP_1,22*FP_1,0,FP_1*5/2,-27*FP_1,0,0,OFFSET upperStairMap3D,MODE_STAIRS,0,85,2
@@:
cmp basementDoorOpen3D,0
je interior_views_done
cmp playerX,29*FP_1
jae interior_views_done
invoke DrawInteriorView3D,0,FP_1*2895/100,FP_1*975/100,FP_1*1125/100,0,FP_1*19/10,-25*FP_1,FP_1*21/2,FP_1*3/2,OFFSET basementStairMap3D,MODE_STAIRS,0,94,1
ret
interior_views_lounge:
cmp playerX,FP_1*32/10
jbe interior_views_done
invoke DrawInteriorView3D,0,FP_1*325/100,20*FP_1,22*FP_1,0,FP_1*5/2,12*FP_1,0,FP_1*13/5,OFFSET upperStairMap3D,MODE_STAIRS,2,85,2
ret
interior_views_bunker:
cmp playerY,FP_1*277/10
jae interior_views_done
invoke DrawInteriorView3D,1,FP_1*2765/100,15*FP_1,18*FP_1,0,FP_1*5/2,0,-13*FP_1,0,OFFSET basementStairMap3D,MODE_STAIRS,1,94,1
ret
interior_views_stairs:
cmp stairRoute3D,1
je interior_views_concrete
cmp playerX,FP_1*31/10
jbe @F
invoke DrawInteriorView3D,0,FP_1*315/100,20*FP_1,22*FP_1,0,FP_1*5/2,27*FP_1,0,0,OFFSET casinoMap,MODE_WALK,0,100,0
@@:
cmp playerX,16*FP_1
jae interior_views_done
invoke DrawInteriorView3D,0,FP_1*159/10,20*FP_1,22*FP_1,FP_1*13/5,FP_1*51/10,-12*FP_1,0,-FP_1*13/5,OFFSET upperLoungeMap3D,MODE_WALK,2,124,0
ret
interior_views_concrete:
cmp playerX,FP_1*31/10
jbe @F
invoke DrawInteriorView3D,0,FP_1*315/100,FP_1*2025/100,FP_1*2175/100,FP_1*3/2,FP_1*34/10,25*FP_1,-FP_1*21/2,-FP_1*3/2,OFFSET casinoMap,MODE_WALK,0,100,0
@@:
cmp playerY,FP_1*143/10
jbe interior_views_done
invoke DrawInteriorView3D,1,FP_1*144/10,15*FP_1,18*FP_1,0,FP_1*5/2,0,13*FP_1,0,OFFSET bunkerMap3D,MODE_WALK,1,94,0
interior_views_done:
ret
RenderInteriorViews3D ENDP