.data? cityRayX3D dd SCREEN_W dup(?) cityRayY3D dd SCREEN_W dup(?) .code ; Exterior-only materials do not consume or overwrite the hall's texture slots. ResolveCitySurface3D PROC material:DWORD mov eax,material cmp eax,161 jb @F cmp eax,163 ja @F invoke ResolveJackboxSurface3D,material ret @@: cmp eax,160 jne @F call ResolveDartsSurface3D ret @@: cmp eax,132 jb @F cmp eax,159 ja @F invoke ResolveFortuneMaterial3D,material ret @@: cmp eax,122 jb @F cmp eax,131 ja @F invoke ResolveUpperMaterial3D,material ret @@: cmp eax,118 jb @F cmp eax,122 jae @F invoke ResolveTerminalSurface3D,material ret @@: cmp eax,115 jb @F cmp eax,118 jae @F invoke ResolveDressingSurface3D,material ret @@: cmp eax,111 jb city_surface_shared cmp eax,115 jae city_surface_shared cmp cityDecorPack3D.pixels,0 je city_surface_missing sub eax,111 shl eax,16 add eax,cityDecorPack3D.pixels mov ecx,128 mov edx,128 ret city_surface_missing: xor eax,eax ret city_surface_shared: invoke ResolveWorldSurface3D,material ret ResolveCitySurface3D ENDP PrepareCityDepth3D PROC uses ebx esi edi lea edi, cityDepthBuffer3D mov ebx, SCREEN_H city_depth_row: lea esi, zBuffer xor ecx, ecx city_depth_column: mov eax, [esi+ecx*4] cmp outdoorRender3D, 0 je city_depth_store ; Preserve per-pixel district depth when foreground walls have no hit. cmp eax, [edi] jle city_depth_store mov eax, [edi] city_depth_store: stosd inc ecx cmp ecx, SCREEN_W jb city_depth_column dec ebx jnz city_depth_row call PrepareCityRays3D ret PrepareCityDepth3D ENDP PrepareCityRays3D PROC uses ebx esi xor ebx, ebx city_prepare_ray: mov eax, ebx imul eax, 2*FP_1 xor edx, edx mov ecx, SCREEN_W div ecx sub eax, FP_1 mov esi, eax imul playerPlaneX shrd eax, edx, 16 add eax, playerDirX mov cityRayX3D[ebx*4], eax mov eax, esi imul playerPlaneY shrd eax, edx, 16 add eax, playerDirY mov cityRayY3D[ebx*4], eax inc ebx cmp ebx, SCREEN_W jb city_prepare_ray ret PrepareCityRays3D ENDP CityRayPlane3D PROC coordinate:DWORD,origin:DWORD,direction:DWORD mov ecx, direction mov eax, ecx test eax, eax jns @F neg eax @@: cmp eax, 256 jb city_ray_parallel mov eax, coordinate sub eax, origin cdq shld edx, eax, 16 shl eax, 16 idiv ecx ret city_ray_parallel: mov eax, 7FFFFFFFh ret CityRayPlane3D ENDP ; Vertical surfaces intersect actual rays, rather than turning to face the camera. DrawCityVertical3D PROC uses ebx esi edi axis:DWORD,coordinate:DWORD,loBound:DWORD,hiBound:DWORD,zLow:DWORD,zHigh:DWORD,material:DWORD local depth:DWORD,top:DWORD,bottom:DWORD,span:DWORD,column:DWORD local sourceX:DWORD,stepY:DWORD,sourceY:DWORD,destination:DWORD,row:DWORD,texture:DWORD local textureW:DWORD,textureH:DWORD invoke ResolveCitySurface3D,material test eax, eax jz city_vertical_done mov texture, eax mov textureW, ecx mov textureH, edx mov column, 0 city_vertical_column: mov ebx, column cmp axis, 0 jne city_vertical_y_plane invoke CityRayPlane3D, coordinate, playerX, cityRayX3D[ebx*4] cmp eax, 4096 jle city_vertical_next_column cmp cityBackdrop3D, 0 jne @F cmp eax, zBuffer[ebx*4] jae city_vertical_next_column @@: mov depth, eax imul cityRayY3D[ebx*4] shrd eax, edx, 16 add eax, playerY jmp city_vertical_along city_vertical_y_plane: invoke CityRayPlane3D, coordinate, playerY, cityRayY3D[ebx*4] cmp eax, 4096 jle city_vertical_next_column cmp cityBackdrop3D, 0 jne @F cmp eax, zBuffer[ebx*4] jae city_vertical_next_column @@: mov depth, eax imul cityRayX3D[ebx*4] shrd eax, edx, 16 add eax, playerX city_vertical_along: cmp eax, loBound jl city_vertical_next_column cmp eax, hiBound jge city_vertical_next_column sub eax, loBound imul eax, textureW cdq mov ecx, hiBound sub ecx, loBound idiv ecx cmp cityBackdrop3D, 0 je @F imul ecx shrd eax, edx, 16 mov edx, textureW dec edx and eax, edx @@: mov sourceX, eax mov eax, viewEye3D sub eax, zHigh imul eax, SCREEN_H cdq idiv depth add eax, viewHorizon3D mov top, eax mov eax, viewEye3D sub eax, zLow imul eax, SCREEN_H cdq idiv depth add eax, viewHorizon3D mov bottom, eax sub eax, top jle city_vertical_next_column mov span, eax mov eax, textureH shl eax, 16 xor edx, edx div span cmp cityBackdrop3D, 0 je @F mov ecx, zHigh sub ecx, zLow imul ecx shrd eax, edx, 16 @@: 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 city_vertical_next_column imul eax, SCREEN_W add eax, column shl eax, 2 mov destination, eax city_vertical_pixel: mov edi, destination mov eax, depth cmp portalRendering3D,0 je @F mov ebx,column cmp eax,portalClipDepth3D[ebx*4] jb city_vertical_next_pixel @@: cmp eax, cityDepthBuffer3D[edi] ja city_vertical_next_pixel mov eax, sourceY shr eax, 16 mov edx, textureH dec edx and eax, edx imul eax, textureW add eax, sourceX mov esi, texture mov eax, [esi+eax*4] cmp material, 104 jb @F cmp eax, 80000000h jb city_vertical_next_pixel @@: mov edx, depth mov cityDepthBuffer3D[edi], edx and eax, 00FFFFFFh cmp cityBackdrop3D, 0 je @F push eax push ecx invoke IsCityEmissive3D, eax, material pop ecx test eax, eax pop eax jnz @F and eax, 00FEFEFEh shr eax, 1 add eax, 00101828h @@: mov screenBuffer[edi], eax city_vertical_next_pixel: mov eax, stepY add sourceY, eax add destination, SCREEN_W*4 inc row mov eax, row cmp eax, bottom jb city_vertical_pixel city_vertical_next_column: inc column cmp column, SCREEN_W jb city_vertical_column city_vertical_done: ret DrawCityVertical3D ENDP DrawCityHorizontal3D PROC uses ebx esi edi xMin:DWORD,xMax:DWORD,yMin:DWORD,yMax:DWORD,z:DWORD,material:DWORD local left:DWORD,right:DWORD,top:DWORD,bottom:DWORD,corner:DWORD,pointX:DWORD,pointY:DWORD local depth:DWORD,row:DWORD,column:DWORD,stepX:DWORD,stepY:DWORD,scaleX:DWORD,scaleY:DWORD,texture:DWORD local textureW:DWORD,textureH:DWORD,nearClipped:DWORD invoke ResolveCitySurface3D,material test eax, eax jz city_horizontal_done mov texture, eax mov textureW, ecx mov textureH, edx mov nearClipped, 0 mov left, SCREEN_W mov right, 0 mov top, SCREEN_H mov bottom, 0 mov corner, 0 city_horizontal_corner: mov eax, xMin test corner, 1 jz @F mov eax, xMax @@: mov ebx, yMin test corner, 2 jz @F mov ebx, yMax @@: invoke ProjectCityPoint3D, eax, ebx cmp edx, 4096 jg city_horizontal_visible_corner mov nearClipped, 1 jmp city_horizontal_next_corner city_horizontal_visible_corner: mov esi, edx cmp eax, left jge @F mov left, eax @@: cmp eax, right jle @F mov right, eax @@: mov eax, viewEye3D sub eax, z imul eax, SCREEN_H cdq idiv esi add eax, viewHorizon3D cmp eax, top jge @F mov top, eax @@: cmp eax, bottom jle @F mov bottom, eax @@: city_horizontal_next_corner: inc corner cmp corner, 4 jb city_horizontal_corner cmp nearClipped, 0 je @F ; Ray bounds/depth below clip the polygon; a behind-camera corner cannot discard it. mov left, 0 mov right, SCREEN_W-1 mov top, 0 mov bottom, SCREEN_H-1 @@: cmp left, 0 jge @F mov left, 0 @@: cmp right, SCREEN_W-1 jle @F mov right, SCREEN_W-1 @@: cmp top, 0 jge @F mov top, 0 @@: cmp bottom, SCREEN_H-1 jle @F mov bottom, SCREEN_H-1 @@: mov eax, left cmp eax, right jge city_horizontal_done mov eax, top cmp eax, bottom jge city_horizontal_done mov row, eax xor eax, eax mov edx, textureW mov ecx, xMax sub ecx, xMin idiv ecx mov scaleX, eax xor eax, eax mov edx, textureH mov ecx, yMax sub ecx, yMin idiv ecx mov scaleY, eax city_horizontal_row: mov ecx, row sub ecx, viewHorizon3D jz city_horizontal_next_row mov eax, viewEye3D sub eax, z imul eax, SCREEN_H cdq idiv ecx cmp eax, 4096 jle city_horizontal_next_row mov depth, eax mov ebx, left imul cityRayX3D[ebx*4] shrd eax, edx, 16 add eax, playerX mov pointX, eax mov eax, depth imul cityRayY3D[ebx*4] shrd eax, edx, 16 add eax, playerY mov pointY, eax mov eax, depth imul playerPlaneX shrd eax, edx, 16 shl eax, 1 cdq mov ecx, SCREEN_W idiv ecx mov stepX, eax mov eax, depth imul playerPlaneY shrd eax, edx, 16 shl eax, 1 cdq idiv ecx mov stepY, eax mov column, ebx mov eax, row imul eax, SCREEN_W*4 lea edi, [eax+ebx*4] city_horizontal_pixel: mov eax, pointX cmp eax, xMin jl city_horizontal_advance cmp eax, xMax jge city_horizontal_advance mov eax, pointY cmp eax, yMin jl city_horizontal_advance cmp eax, yMax jge city_horizontal_advance mov eax, depth cmp portalRendering3D,0 je @F mov ebx,column cmp eax,portalClipDepth3D[ebx*4] jb city_horizontal_advance @@: cmp eax, cityDepthBuffer3D[edi] ja city_horizontal_advance mov eax, pointX sub eax, xMin imul scaleX mov esi, edx mov ecx, textureW dec ecx and esi, ecx mov eax, pointY sub eax, yMin imul scaleY mov ecx, textureH dec ecx and edx, ecx imul edx, textureW add esi, edx mov ebx, texture mov eax, [ebx+esi*4] cmp outdoorRender3D,0 je city_horizontal_alpha cmp material,72 jne city_horizontal_alpha mov ecx,depth shr ecx,14 neg ecx add ecx,256 cmp ecx,55 jge @F mov ecx,55 @@: invoke ShadeCityGround3D,eax,pointX,pointY,ecx city_horizontal_alpha: cmp material, 104 jb @F cmp eax, 80000000h jb city_horizontal_advance @@: mov ecx, depth mov cityDepthBuffer3D[edi], ecx and eax, 00FFFFFFh mov screenBuffer[edi], eax city_horizontal_advance: mov eax, stepX add pointX, eax mov eax, stepY add pointY, eax add edi, 4 inc column mov eax, column cmp eax, right jbe city_horizontal_pixel city_horizontal_next_row: inc row mov eax, row cmp eax, bottom jbe city_horizontal_row city_horizontal_done: ret DrawCityHorizontal3D ENDP DrawCityBoxSides3D PROC xMin:DWORD,xMax:DWORD,yMin:DWORD,yMax:DWORD,zLow:DWORD,zHigh:DWORD,material:DWORD invoke DrawCityVertical3D, 0, xMin, yMin, yMax, zLow, zHigh, material invoke DrawCityVertical3D, 0, xMax, yMin, yMax, zLow, zHigh, material invoke DrawCityVertical3D, 1, yMin, xMin, xMax, zLow, zHigh, material invoke DrawCityVertical3D, 1, yMax, xMin, xMax, zLow, zHigh, material ret DrawCityBoxSides3D ENDP DrawCityBinBodies3D PROC cmp cityBinPack3D.pixels, 0 je city_bin_bodies_done invoke DrawCityBoxSides3D, FP_1*181/20,FP_1*197/20,FP_1*261/10,FP_1*55/2,FP_1/12,FP_1*2/3,73 invoke DrawCityBoxSides3D, FP_1*163/20,FP_1*44/5,FP_1*132/5,FP_1*139/5,FP_1/12,FP_1*13/20,73 city_bin_bodies_done: ret DrawCityBinBodies3D ENDP RenderCityBins3D PROC uses ebx esi edi local wx:DWORD,wy:DWORD cmp cityBinPack3D.pixels, 0 je city_bins_done ; Ground contact patches and closed, low-profile dumpster lids. invoke DrawCityHorizontal3D, FP_1*179/20,FP_1*199/20,26*FP_1,FP_1*138/5,FP_1/1000,76 invoke DrawCityHorizontal3D, FP_1*161/20,FP_1*89/10,FP_1*263/10,FP_1*279/10,FP_1/1000,76 call DrawCityBinBodies3D invoke DrawCityBoxSides3D, FP_1*163/20-FP_1/40,FP_1*44/5+FP_1/40,FP_1*132/5-FP_1/40,FP_1*139/5+FP_1/40,FP_1*13/20,FP_1*7/10,76 invoke DrawCityHorizontal3D, FP_1*163/20-FP_1/40,FP_1*44/5+FP_1/40,FP_1*132/5-FP_1/40,FP_1*139/5+FP_1/40,FP_1*7/10,74 invoke DrawCityBoxSides3D, FP_1*83/10,FP_1*43/5,FP_1*133/5,FP_1*267/10,FP_1*7/10,FP_1*3/4,76 invoke DrawCityHorizontal3D, FP_1*83/10,FP_1*43/5,FP_1*133/5,FP_1*267/10,FP_1*3/4,74 invoke DrawCityHorizontal3D, FP_1*181/20,FP_1*197/20,FP_1*261/10,FP_1*55/2,FP_1*11/20,75 invoke DrawCityHorizontal3D, FP_1*181/20,FP_1*181/20+FP_1/24,FP_1*261/10,FP_1*55/2,FP_1*2/3,73 invoke DrawCityHorizontal3D, FP_1*197/20-FP_1/24,FP_1*197/20,FP_1*261/10,FP_1*55/2,FP_1*2/3,73 invoke DrawCityHorizontal3D, FP_1*181/20,FP_1*197/20,FP_1*261/10,FP_1*261/10+FP_1/24,FP_1*2/3,73 invoke DrawCityHorizontal3D, FP_1*181/20,FP_1*197/20,FP_1*55/2-FP_1/24,FP_1*55/2,FP_1*2/3,73 invoke DrawCityBoxSides3D, FP_1*181/20-FP_1/40,FP_1*197/20+FP_1/40,FP_1*261/10,FP_1*55/2,FP_1*2/3,FP_1*3/4,76 invoke DrawCityHorizontal3D, FP_1*181/20-FP_1/40,FP_1*197/20+FP_1/40,FP_1*261/10,FP_1*55/2,FP_1*3/4,74 invoke DrawCityBoxSides3D, FP_1*93/10,FP_1*48/5,FP_1*261/10-FP_1/20,FP_1*261/10,FP_1*11/20,FP_1*3/5,76 invoke DrawCityBoxSides3D, FP_1*17/2,FP_1*171/20,FP_1*132/5-FP_1/20,FP_1*132/5,FP_1*11/20,FP_1*3/5,76 xor esi, esi city_bin_wheel: mov wx, FP_1*183/20 mov wy, FP_1*263/10 test esi, 1 jz @F mov wx, FP_1*193/20 @@: test esi, 2 jz @F mov wy, FP_1*273/10 @@: mov ebx, wx add ebx, FP_1/8 mov edi, wy add edi, FP_1/8 invoke DrawCityBoxSides3D, wx,ebx,wy,edi,0,FP_1/10,76 add wx, -(FP_1) mov eax, wx add eax, FP_1/8 invoke DrawCityBoxSides3D, wx,eax,wy,edi,0,FP_1/10,76 inc esi cmp esi, 4 jb city_bin_wheel invoke ProjectCityPoint3D, FP_1*189/20,FP_1*134/5 mov cityMouthX3D, eax mov esi, edx cmp esi, 4096 jle city_bins_done mov eax, viewEye3D sub eax, FP_1*11/20 imul eax, SCREEN_H cdq idiv esi add eax, viewHorizon3D mov cityMouthY3D, eax city_bins_done: ret RenderCityBins3D ENDP