; Exterior props use the same camera and wall depth as the raycaster. PrepareCityStreetCrops3D PROC uses ebx esi edi local frame:DWORD,minX:DWORD,minY:DWORD,maxX:DWORD,maxY:DWORD,x:DWORD,y:DWORD cmp hallStreetLife3D.pixels, 0 je city_crops_done cmp hallStreetLife3D.frames, 40 jne city_crops_done cmp hallStreetLife3D.imageWidth, 192 jne city_crops_done cmp hallStreetLife3D.height, 320 jne city_crops_done mov frame, 32 city_crop_frame: mov minX, 192 mov minY, 320 mov maxX, 0 mov maxY, 0 mov eax, frame imul eax, 192*320*4 add eax, hallStreetLife3D.pixels mov edi, eax mov y, 0 city_crop_row: mov x, 0 city_crop_pixel: cmp BYTE PTR [edi+3], 128 jb city_crop_next mov eax, x cmp eax, minX jae @F mov minX, eax @@: inc eax cmp eax, maxX jbe @F mov maxX, eax @@: mov eax, y cmp eax, minY jae @F mov minY, eax @@: inc eax cmp eax, maxY jbe city_crop_next mov maxY, eax city_crop_next: add edi, 4 inc x cmp x, 192 jb city_crop_pixel inc y cmp y, 320 jb city_crop_row mov eax, frame sub eax, 32 imul esi, eax, SIZEOF CitySpriteCrop3D mov eax, maxX sub eax, minX jle city_crop_advance mov cityStreetCrops3D[esi].pixelW, eax mov eax, maxY sub eax, minY mov cityStreetCrops3D[esi].pixelH, eax mov eax, minX mov cityStreetCrops3D[esi].pixelX, eax mov eax, minY mov cityStreetCrops3D[esi].pixelY, eax city_crop_advance: inc frame cmp frame, 40 jb city_crop_frame city_crops_done: ret PrepareCityStreetCrops3D ENDP ProjectCityPoint3D PROC uses ebx esi wx:DWORD,wy:DWORD local relX:DWORD,relY:DWORD,depth:DWORD mov eax, wx sub eax, playerX mov relX, eax mov eax, wy sub eax, playerY mov relY, eax mov eax, relX imul playerDirX shrd eax, edx, 16 mov ebx, eax mov eax, relY imul playerDirY shrd eax, edx, 16 add eax, ebx mov depth, eax cmp eax, 4096 jle city_project_behind mov eax, relY imul playerDirX shrd eax, edx, 16 mov ebx, eax mov eax, relX imul playerDirY shrd eax, edx, 16 sub ebx, eax mov eax, ebx mov ecx, HALF_W*100 imul ecx mov ecx, depth imul ecx, 66 idiv ecx add eax, HALF_W mov edx, depth ret city_project_behind: xor eax, eax mov edx, depth ret ProjectCityPoint3D ENDP DrawCityObject3D PROC uses ebx esi edi object:DWORD,firstSourceRow:DWORD local depth:DWORD,left:DWORD,top:DWORD,widthPx:DWORD,heightPx:DWORD local xRight:DWORD,yEnd:DWORD,xStart:DWORD,yStart:DWORD local xStep:DWORD,yStep:DWORD,texColumn:DWORD,source:DWORD,row:DWORD,asset:DWORD local sourceWidth:DWORD,sourceHeight:DWORD,sourcePitch:DWORD,cropX:DWORD,cropY:DWORD IFDEF CASINO_ACTION_TEST local ownerIndex:DWORD mov ownerIndex, -1 mov eax, object cmp eax, OFFSET cityObjects3D jb @F cmp eax, OFFSET cityObjectsEnd3D jae @F sub eax, OFFSET cityObjects3D xor edx, edx mov ecx, SIZEOF CityProp3D div ecx mov ownerIndex, eax @@: ENDIF mov esi, object mov ebx, [esi].CityProp3D.asset mov asset, ebx mov eax, [ebx].AnimPack3D.imageWidth mov sourceWidth, eax shl eax, 2 mov sourcePitch, eax mov eax, [ebx].AnimPack3D.height mov sourceHeight, eax mov cropX, 0 mov cropY, 0 cmp [ebx].AnimPack3D.pixels, 0 je city_object_done mov eax, [esi].CityProp3D.frame cmp eax, [ebx].AnimPack3D.frames jae city_object_done cmp asset, OFFSET hallStreetLife3D jne city_object_project cmp eax, 32 jb city_object_project cmp eax, 40 jae city_object_project sub eax, 32 imul ebx, eax, SIZEOF CitySpriteCrop3D mov eax, cityStreetCrops3D[ebx].pixelW test eax, eax jz city_object_project mov sourceWidth, eax mov eax, cityStreetCrops3D[ebx].pixelH mov sourceHeight, eax mov eax, cityStreetCrops3D[ebx].pixelX mov cropX, eax mov eax, cityStreetCrops3D[ebx].pixelY mov cropY, eax city_object_project: invoke ProjectCityPoint3D, [esi].CityProp3D.posX, [esi].CityProp3D.posY cmp edx, 4096 jle city_object_done mov depth, edx mov ebx, eax mov eax, SCREEN_H imul [esi].CityProp3D.worldW idiv depth test eax, eax jle city_object_done cmp eax, 4096 ja city_object_done mov widthPx, eax shr eax, 1 sub ebx, eax mov left, ebx mov eax, SCREEN_H imul [esi].CityProp3D.worldH idiv depth test eax, eax jle city_object_done cmp eax, 4096 ja city_object_done mov heightPx, eax mov eax, viewEye3D sub eax, [esi].CityProp3D.groundZ imul eax, SCREEN_H cdq idiv depth add eax, viewHorizon3D sub eax, heightPx mov top, eax cmp asset, OFFSET cityPropsPack3D jne @F cmp [esi].CityProp3D.frame, 0 jne @F mov eax, widthPx shr eax, 1 add eax, left mov cityMouthX3D, eax mov eax, heightPx imul eax, 110 shr eax, 8 add eax, top mov cityMouthY3D, eax @@: mov eax, left mov xStart, eax add eax, widthPx cmp eax, SCREEN_W jle @F mov eax, SCREEN_W @@: mov xRight, eax cmp xStart, 0 jge @F mov xStart, 0 @@: mov eax, top mov yStart, eax add eax, heightPx cmp eax, SCREEN_H jle @F mov eax, SCREEN_H @@: mov yEnd, eax cmp yStart, 0 jge @F mov yStart, 0 @@: mov eax, xStart cmp eax, xRight jge city_object_done mov eax, yStart cmp eax, yEnd jge city_object_done mov eax, sourceWidth shl eax, 16 xor edx, edx div widthPx mov xStep, eax mov eax, sourceHeight shl eax, 16 xor edx, edx div heightPx mov yStep, eax mov ebx, asset mov eax, [esi].CityProp3D.frame imul eax, [ebx].AnimPack3D.imageWidth imul eax, [ebx].AnimPack3D.height shl eax, 2 add eax, [ebx].AnimPack3D.pixels mov edx, cropY imul edx, sourcePitch add eax, edx mov edx, cropX lea eax, [eax+edx*4] mov source, eax mov ebx, xStart city_object_column: mov eax, depth cmp eax, zBuffer[ebx*4] jge city_object_next_column mov eax, ebx sub eax, left imul eax, xStep shr eax, 16 mov texColumn, eax mov eax, yStart mov row, eax imul eax, SCREEN_W*4 lea edi, screenBuffer[eax+ebx*4] mov ecx, yStart sub ecx, top imul ecx, yStep city_object_row: mov eax, ecx shr eax, 16 cmp eax, firstSourceRow jb city_object_next_row imul eax, sourcePitch mov edx, texColumn lea eax, [eax+edx*4] mov esi, source mov eax, [esi+eax] cmp asset, OFFSET hallLegacyPack3D jne @F and eax, 00FFFFFFh cmp eax, CHROMA_KEY je city_object_next_row jmp city_object_test_depth @@: cmp eax, 80000000h jb city_object_next_row city_object_test_depth: mov esi, edi sub esi, OFFSET screenBuffer mov eax, depth cmp eax, cityDepthBuffer3D[esi] jae city_object_next_row mov cityDepthBuffer3D[esi], eax IFDEF CASINO_ACTION_TEST mov eax, ownerIndex mov cityPixelOwner3D[esi], eax ENDIF mov esi, source mov eax, ecx shr eax, 16 imul eax, sourcePitch mov edx, texColumn lea eax, [eax+edx*4] mov eax, [esi+eax] and eax, 00FFFFFFh mov [edi], eax city_object_next_row: add ecx, yStep add edi, SCREEN_W*4 inc row mov eax, row cmp eax, yEnd jb city_object_row city_object_next_column: inc ebx cmp ebx, xRight jb city_object_column city_object_done: ret DrawCityObject3D ENDP RenderCityObjects3D PROC uses ebx esi edi IFDEF CASINO_ACTION_TEST lea edi, cityPixelOwner3D mov eax, -1 mov ecx, SCREEN_SIZE rep stosd lea edi, cityVisiblePixels3D xor eax, eax mov ecx, CITY_PROP_COUNT rep stosd ENDIF call AnimateCityCars3D call AnimateCityPedestrians3D call UpdateStreetGround3D xor esi, esi city_objects_depth: imul ebx, esi, SIZEOF CityProp3D invoke ProjectCityPoint3D, cityObjects3D[ebx].posX, cityObjects3D[ebx].posY mov cityObjectDepth3D[esi*4], edx mov cityObjectOrder3D[esi*4], esi inc esi cmp esi, CITY_PROP_COUNT jb city_objects_depth xor esi, esi city_objects_sort_outer: mov edi, esi inc edi city_objects_sort_inner: mov eax, cityObjectOrder3D[esi*4] mov ebx, cityObjectDepth3D[eax*4] mov edx, cityObjectOrder3D[edi*4] cmp ebx, cityObjectDepth3D[edx*4] jge @F mov cityObjectOrder3D[esi*4], edx mov cityObjectOrder3D[edi*4], eax @@: inc edi cmp edi, CITY_PROP_COUNT jb city_objects_sort_inner inc esi cmp esi, CITY_PROP_COUNT-1 jb city_objects_sort_outer xor esi, esi city_objects_draw: mov eax, cityObjectOrder3D[esi*4] cmp eax, 2 jb city_objects_skip imul eax, SIZEOF CityProp3D add eax, OFFSET cityObjects3D invoke DrawCityObject3D, eax, 0 city_objects_skip: inc esi cmp esi, CITY_PROP_COUNT jb city_objects_draw IFDEF CASINO_ACTION_TEST xor esi, esi city_visible_count: mov eax, cityPixelOwner3D[esi*4] cmp eax, CITY_PROP_COUNT jae @F inc cityVisiblePixels3D[eax*4] @@: inc esi cmp esi, SCREEN_SIZE jb city_visible_count ENDIF ret RenderCityObjects3D ENDP