- Native player-controlled stairs, upper lounge bar, and Hell Tower infernal portal - Cabaret stage with musical acts, audience seating, and interaction - Dedicated cash/trophy wall terminals with native balance and achievement screens - Projecting 3D wall lanterns with ray/plane intersection - Six roaming guests with seated poses and card rank rendering updates - Synchronized launcher hash and updated binaries
588 lines
14 KiB
PHP
588 lines
14 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,122
|
|
jb @F
|
|
cmp eax,130
|
|
ja @F
|
|
invoke ResolveUpperMaterial3D,material
|
|
ret
|
|
@@:
|
|
cmp eax,118
|
|
jb @F
|
|
cmp eax,122
|
|
jae @F
|
|
invoke ResolveTerminalSurface3D,material
|
|
ret
|
|
@@:
|
|
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 portalRendering3D,0
|
|
je @F
|
|
mov ebx,column
|
|
cmp eax,portalClipDepth3D[ebx*4]
|
|
jb city_vertical_next_pixel
|
|
@@:
|
|
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 portalRendering3D,0
|
|
je @F
|
|
mov ebx,column
|
|
cmp eax,portalClipDepth3D[ebx*4]
|
|
jb city_horizontal_advance
|
|
@@:
|
|
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
|