242 lines
5 KiB
PHP
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
|