KAZIK/src_graphics/city_bins.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

562 lines
13 KiB
PHP

.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,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 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 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