KAZIK/src_graphics/city_lighting.inc

242 lines
5 KiB
PHP

; Static world-space lightmap: built once, sampled without walking the light list.
.code
AddCityLight3D PROC uses ebx esi edi x:DWORD,y:DWORD,rx:DWORD,ry:DWORD,power:DWORD
local gx:DWORD,gy:DWORD,minX:DWORD,maxX:DWORD,maxY:DWORD,dy2:DWORD
mov eax, x
sub eax, rx
jns @F
xor eax, eax
@@:
mov minX, eax
mov eax, x
add eax, rx
cmp eax, CITY_LIGHT_W-1
jle @F
mov eax, CITY_LIGHT_W-1
@@:
mov maxX, eax
mov eax, y
sub eax, ry
jns @F
xor eax, eax
@@:
mov gy, eax
mov eax, y
add eax, ry
cmp eax, CITY_LIGHT_H-1
jle @F
mov eax, CITY_LIGHT_H-1
@@:
mov maxY, eax
city_light_row:
mov eax, gy
sub eax, y
imul eax, 256
cdq
idiv ry
imul eax, eax
mov dy2, eax
mov eax, minX
mov gx, eax
city_light_cell:
mov eax, gx
sub eax, x
imul eax, 256
cdq
idiv rx
imul eax, eax
add eax, dy2
cmp eax, 65536
jae city_light_next
neg eax
add eax, 65536
mov ecx, eax
mul ecx
shrd eax, edx, 16
imul eax, power
shr eax, 16
mov ebx, gy
shl ebx, 9
add ebx, gx
add eax, cityLightMap3D[ebx*4]
cmp eax, 320
jbe @F
mov eax, 320
@@:
mov cityLightMap3D[ebx*4], eax
city_light_next:
inc gx
mov eax, gx
cmp eax, maxX
jle city_light_cell
inc gy
mov eax, gy
cmp eax, maxY
jle city_light_row
ret
AddCityLight3D ENDP
BuildCityLighting3D PROC uses ebx esi edi
lea edi, cityLightMap3D
xor eax, eax
mov ecx, CITY_LIGHT_W*CITY_LIGHT_H
rep stosd
lea esi, cityObjects3D
mov ebx, CITY_PROP_COUNT
city_light_lamp:
cmp [esi].CityProp3D.asset, OFFSET cityPropsPack3D
jne city_light_lamp_next
cmp [esi].CityProp3D.frame, 3
jne city_light_lamp_next
mov eax, [esi].CityProp3D.posX
sar eax, 13
mov edx, [esi].CityProp3D.posY
sar edx, 13
invoke AddCityLight3D, eax, edx, 25, 25, 240
city_light_lamp_next:
add esi, SIZEOF CityProp3D
dec ebx
jnz city_light_lamp
; Only genuinely lit windows/storefronts cast a narrower spill across the curb.
mov esi, 3
city_light_windows:
movzx eax, cityMap3D[11*32+esi]
cmp eax, 65
je city_light_near_window
cmp eax, 62
jne city_light_far_window
city_light_near_window:
lea eax, [esi*8+4]
invoke AddCityLight3D, eax, 12*8+2, 7, 16, 96
city_light_far_window:
movzx eax, cityMap3D[17*32+esi]
cmp eax, 65
jne city_light_next_window
lea eax, [esi*8+4]
invoke AddCityLight3D, eax, 17*8-2, 7, 16, 96
city_light_next_window:
inc esi
cmp esi, 29
jb city_light_windows
; The casino door is at y=8; this does not illuminate an imaginary closed facade.
invoke AddCityLight3D, 22*8+4, 8*8+2, 14, 22, 150
mov cityLightReady3D, 1
ret
BuildCityLighting3D ENDP
SampleCityLight3D PROC x:DWORD,y:DWORD
xor eax, eax
cmp cityLighting3D, 0
je city_light_sample_done
cmp cityLightReady3D, 0
je city_light_sample_done
mov ecx, x
sar ecx, 13
cmp ecx, CITY_LIGHT_W
jae city_light_sample_zero
mov edx, y
sar edx, 13
cmp edx, CITY_LIGHT_H
jae city_light_sample_zero
shl edx, 9
add edx, ecx
mov eax, cityLightMap3D[edx*4]
ret
city_light_sample_zero:
xor eax, eax
city_light_sample_done:
ret
SampleCityLight3D ENDP
ShadeCityGround3D PROC uses ebx esi edi rgb:DWORD,x:DWORD,y:DWORD,ambient:DWORD
invoke SampleCityLight3D, x, y
mov esi, eax
; Tint the material itself, retaining paving detail instead of painting a flat glow.
mov eax, rgb
shr eax, 16
and eax, 255
mov ecx, ambient
add ecx, esi
imul eax, ecx
shr eax, 8
cmp eax, 255
jbe @F
mov eax, 255
@@:
shl eax, 16
mov edi, eax
mov eax, rgb
shr eax, 8
and eax, 255
mov ecx, esi
imul ecx, 3
shr ecx, 2
add ecx, ambient
imul eax, ecx
shr eax, 8
cmp eax, 255
jbe @F
mov eax, 255
@@:
shl eax, 8
or edi, eax
mov eax, rgb
and eax, 255
mov ecx, esi
shr ecx, 2
add ecx, ambient
imul eax, ecx
shr eax, 8
cmp eax, 255
jbe @F
mov eax, 255
@@:
or eax, edi
ret
ShadeCityGround3D ENDP
; Bright warm panes and lantern glass emit light; dark windows/brick do not.
IsCityEmissive3D PROC uses ebx rgb:DWORD,material:DWORD
cmp material,242
jb @F
cmp material,BW_LAST_MATERIAL
ja @F
mov eax,1
ret
@@:
cmp cityLighting3D, 0
je city_not_emissive
mov eax, material
cmp eax, 58
je city_emissive_color
cmp eax, 62
je city_emissive_color
cmp eax, 65
je city_emissive_color
cmp eax, 70
jne city_not_emissive
city_emissive_color:
mov eax, rgb
shr eax, 16
and eax, 255
cmp eax, 180
jb city_not_emissive
mov edx, rgb
shr edx, 8
and edx, 255
cmp edx, 96
jb city_not_emissive
sub eax, edx
cmp eax, 32
jl city_not_emissive
mov ebx, rgb
and ebx, 255
sub edx, ebx
cmp edx, 24
jl city_not_emissive
mov eax, 1
ret
city_not_emissive:
xor eax, eax
ret
IsCityEmissive3D ENDP