KAZIK/src_graphics/city_objects.inc
Игорь Федосеев ca62db53e9 feat: implement native billiards, scratch tickets, first-person dice, and city wake scene
- Billiards: add native Russian Pyramid & American Eight-Ball pool with physics prediction, controls, and regression tests
- Scratch Tickets: add dedicated counter, mat presentation, elliptical coin scraping, 4 ticket types, and payout effects
- First-Person Dice: add native dice scene, hand anchor frames, throwing animation, and table perspective
- City Wake & Weather: add arrival cutscene, alley geometry, weather/rain effects, and lighter/rocker animation
- World Dressing: add hall paintings, furniture packs, hall lighting, and scene regression tests
- Build & Tooling: update build.bat for modern MSVC toolchain, update launcher hash, and refresh shipping binaries
2026-10-16 12:37:40 +03:00

410 lines
9.2 KiB
PHP

; 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