; Ray/plane intersection for real pitched roofs, including perspective depth. DrawRoofSlope3D PROC uses ebx esi edi axis:DWORD,x0:DWORD,x1:DWORD,y0:DWORD,y1:DWORD,baseZ:DWORD,rise:DWORD,material:DWORD local slope:DWORD,numerator:DWORD,leftPx:DWORD,rightPx:DWORD,topPx:DWORD,bottomPx:DWORD local corner:DWORD,wx:DWORD,wy:DWORD,wz:DWORD,visible:DWORD,nearClip:DWORD local row:DWORD,column:DWORD,rayZ:DWORD,depth:DWORD,along:DWORD,denominator:DWORD local texture:DWORD,textureW:DWORD,textureH:DWORD,light:DWORD,sourceU:DWORD invoke ResolveRoofSurface3D,material test eax,eax jz roof_slope_done mov texture,eax mov textureW,ecx mov textureH,edx mov eax,rise cdq shld edx,eax,16 shl eax,16 mov ecx,x1 sub ecx,x0 cmp axis,0 je @F mov ecx,y1 sub ecx,y0 @@: idiv ecx mov slope,eax mov light,242 test eax,eax jns @F mov light,184 @@: mov eax,playerX sub eax,x0 cmp axis,0 je @F mov eax,playerY sub eax,y0 @@: imul slope shrd eax,edx,16 neg eax add eax,viewEye3D sub eax,baseZ mov numerator,eax mov leftPx,SCREEN_W mov rightPx,0 mov topPx,SCREEN_H mov bottomPx,0 mov visible,0 mov nearClip,0 mov corner,0 roof_slope_corner: mov eax,x0 test corner,1 jz @F mov eax,x1 @@: mov wx,eax mov ebx,y0 test corner,2 jz @F mov ebx,y1 @@: mov wy,ebx mov ecx,baseZ mov eax,corner cmp axis,0 jne @F and eax,1 jmp roof_slope_corner_height @@: and eax,2 roof_slope_corner_height: test eax,eax jz @F add ecx,rise @@: mov wz,ecx invoke ProjectCityPoint3D,wx,wy cmp edx,4096 jg roof_slope_projected_corner mov nearClip,1 jmp roof_slope_corner_next roof_slope_projected_corner: inc visible mov esi,edx cmp eax,leftPx jge @F mov leftPx,eax @@: cmp eax,rightPx jle @F mov rightPx,eax @@: mov eax,viewEye3D sub eax,wz mov ecx,SCREEN_H imul ecx idiv esi add eax,viewHorizon3D cmp eax,topPx jge @F mov topPx,eax @@: cmp eax,bottomPx jle @F mov bottomPx,eax @@: roof_slope_corner_next: inc corner cmp corner,4 jb roof_slope_corner cmp visible,0 je roof_slope_done cmp nearClip,0 je @F mov leftPx,0 mov rightPx,SCREEN_W-1 mov topPx,0 mov bottomPx,SCREEN_H-1 @@: cmp leftPx,0 jge @F mov leftPx,0 @@: cmp rightPx,SCREEN_W-1 jle @F mov rightPx,SCREEN_W-1 @@: cmp topPx,0 jge @F mov topPx,0 @@: cmp bottomPx,SCREEN_H-1 jle @F mov bottomPx,SCREEN_H-1 @@: mov eax,leftPx cmp eax,rightPx jge roof_slope_done mov eax,topPx cmp eax,bottomPx jge roof_slope_done mov row,eax mov ebx,leftPx roof_slope_prepare: mov eax,cityRayX3D[ebx*4] cmp axis,0 je @F mov eax,cityRayY3D[ebx*4] @@: imul slope shrd eax,edx,16 mov roofSlopeRay3D[ebx*4],eax inc ebx cmp ebx,rightPx jbe roof_slope_prepare roof_slope_row: mov eax,viewHorizon3D sub eax,row shl eax,16 cdq mov ecx,SCREEN_H idiv ecx mov rayZ,eax mov eax,row imul eax,SCREEN_W*4 mov ebx,leftPx lea edi,[eax+ebx*4] mov column,ebx roof_slope_pixel: mov ebx,column mov ecx,roofSlopeRay3D[ebx*4] sub ecx,rayZ mov denominator,ecx mov eax,ecx cdq xor eax,edx sub eax,edx cmp eax,64 jb roof_slope_advance shl eax,10 mov along,eax mov eax,numerator cdq xor eax,edx sub eax,edx cmp eax,along jae roof_slope_advance mov eax,numerator cdq shld edx,eax,16 shl eax,16 idiv denominator cmp eax,4096 jle roof_slope_advance cmp eax,cityDepthBuffer3D[edi] jae roof_slope_advance mov depth,eax imul cityRayX3D[ebx*4] shrd eax,edx,16 add eax,playerX cmp eax,x0 jl roof_slope_advance cmp eax,x1 jge roof_slope_advance mov wx,eax sub eax,x0 sar eax,9 mov ecx,textureW dec ecx and eax,ecx mov sourceU,eax mov eax,depth imul cityRayY3D[ebx*4] shrd eax,edx,16 add eax,playerY cmp eax,y0 jl roof_slope_advance cmp eax,y1 jge roof_slope_advance mov wy,eax cmp roofSlopeMask3D,0 je roof_slope_sample mov eax,wx sub eax,roofSlopeCentreX3D cdq xor eax,edx sub eax,edx imul roofSlopeHalfY3D shrd eax,edx,16 mov along,eax mov eax,wy sub eax,roofSlopeCentreY3D cdq xor eax,edx sub eax,edx imul roofSlopeHalfX3D shrd eax,edx,16 cmp roofSlopeMask3D,1 jne @F cmp eax,along ja roof_slope_advance jmp roof_slope_sample @@: cmp eax,along jb roof_slope_advance roof_slope_sample: mov eax,wy sub eax,y0 sar eax,9 mov ecx,textureH dec ecx and eax,ecx imul eax,textureW add eax,sourceU mov esi,texture mov eax,[esi+eax*4] invoke ShadeRoofCityPixel3D,eax,depth,light,material mov ecx,edi shr ecx,2 mov edx,roofPixelGlow3D mov roofGlowMask3D[ecx],dl mov screenBuffer[edi],eax mov eax,depth mov cityDepthBuffer3D[edi],eax mov eax,edi shr eax,2 mov roofCityMask3D[eax],1 roof_slope_advance: add edi,4 inc column mov eax,column cmp eax,rightPx jbe roof_slope_pixel inc row mov eax,row cmp eax,bottomPx jbe roof_slope_row roof_slope_done: ret DrawRoofSlope3D ENDP DrawRoofPyramid3D PROC uses ebx esi centreX:DWORD,centreY:DWORD,baseZ:DWORD,halfX:DWORD,halfY:DWORD,height:DWORD,mat:DWORD local x0:DWORD,x1:DWORD,y0:DWORD,y1:DWORD,topZ:DWORD,down:DWORD mov eax,centreX mov roofSlopeCentreX3D,eax sub eax,halfX mov x0,eax mov eax,centreX add eax,halfX mov x1,eax mov eax,centreY mov roofSlopeCentreY3D,eax sub eax,halfY mov y0,eax mov eax,centreY add eax,halfY mov y1,eax mov eax,halfX mov roofSlopeHalfX3D,eax mov eax,halfY mov roofSlopeHalfY3D,eax mov eax,baseZ add eax,height mov topZ,eax mov eax,height neg eax mov down,eax mov roofSlopeMask3D,1 invoke DrawRoofSlope3D,0,x0,centreX,y0,y1,baseZ,height,mat invoke DrawRoofSlope3D,0,centreX,x1,y0,y1,topZ,down,mat mov roofSlopeMask3D,2 invoke DrawRoofSlope3D,1,x0,x1,y0,centreY,baseZ,height,mat invoke DrawRoofSlope3D,1,x0,x1,centreY,y1,topZ,down,mat mov roofSlopeMask3D,0 ret DrawRoofPyramid3D ENDP