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

1011 lines
24 KiB
PHP

; Scripted camera follows a real exterior map; simulation never consumes gameplay RNG.
include src_graphics\city_traffic.inc
include src_graphics\city_objects.inc
include src_graphics\city_bins.inc
include src_graphics\city_furniture.inc
include src_graphics\city_alley.inc
include src_graphics\city_skyline.inc
include src_graphics\city_lighting.inc
ValidateCityPack3D PROC uses esi pack:DWORD,widthPx:DWORD,heightPx:DWORD,count:DWORD
mov esi, pack
mov eax, widthPx
cmp [esi].AnimPack3D.imageWidth, eax
jne city_pack_reject
mov eax, heightPx
cmp [esi].AnimPack3D.height, eax
jne city_pack_reject
mov eax, count
cmp [esi].AnimPack3D.frames, eax
jne city_pack_reject
ret
city_pack_reject:
invoke FreeAnimPack3D, esi
ret
ValidateCityPack3D ENDP
LoadCityArrival3D PROC uses esi edi
invoke LoadAnimPack3D, OFFSET cityTilesPack3D, OFFSET cityTilesPath3D
invoke LoadAnimPack3D, OFFSET cityHandsPack3D, OFFSET cityHandsPath3D
invoke LoadAnimPack3D, OFFSET cityPropsPack3D, OFFSET cityPropsPath3D
invoke LoadAnimPack3D, OFFSET citySmokePack3D, OFFSET citySmokePath3D
invoke LoadAnimPack3D, OFFSET cityCarsPack3D, OFFSET cityCarsPath3D
invoke LoadAnimPack3D, OFFSET cityBinPack3D, OFFSET cityBinPath3D
invoke LoadAnimPack3D, OFFSET cityCloudPack3D, OFFSET cityCloudPath3D
invoke LoadAnimPack3D, OFFSET cityWakePack3D, OFFSET cityWakePath3D
invoke LoadAnimPack3D, OFFSET cityLighterPack3D, OFFSET cityLighterPath3D
invoke LoadAnimPack3D, OFFSET cityKneesPack3D, OFFSET cityKneesPath3D
invoke LoadAnimPack3D, OFFSET citySleevePack3D, OFFSET citySleevePath3D
invoke LoadAnimPack3D, OFFSET cityDecorPack3D, OFFSET cityDecorPath3D
invoke ValidateCityPack3D, OFFSET cityWakePack3D, 192,320,32
invoke ValidateCityPack3D, OFFSET cityLighterPack3D, 256,256,16
invoke ValidateCityPack3D, OFFSET cityKneesPack3D, 640,240,1
invoke ValidateCityPack3D, OFFSET citySleevePack3D, 256,384,1
invoke ValidateCityPack3D, OFFSET cityDecorPack3D, 128,128,4
invoke ValidateCityPack3D, OFFSET cityHandsPack3D, 256, 192, 16
invoke ValidateCityPack3D, OFFSET cityPropsPack3D, 256, 256, 6
invoke ValidateCityPack3D, OFFSET citySmokePack3D, 96, 128, 4
invoke ValidateCityPack3D, OFFSET cityCarsPack3D, 256, 256, 16
invoke ValidateCityPack3D, OFFSET cityBinPack3D, 128, 128, 4
invoke ValidateCityPack3D, OFFSET cityCloudPack3D, 192, 192, 4
call PrepareCityStreetCrops3D
call BuildCityLighting3D
cmp cityBinPack3D.pixels, 0
je @F
mov esi, cityBinPack3D.pixels
lea edi, texturesBuffer[73*128*128*4]
mov ecx, 4*128*128
rep movsd
@@:
cmp cityTilesPack3D.pixels, 0
je city_load_done
cmp cityTilesPack3D.imageWidth, 128
jne city_load_done
cmp cityTilesPack3D.height, 128
jne city_load_done
cmp cityTilesPack3D.frames, 16
jne city_load_done
mov esi, cityTilesPack3D.pixels
lea edi, texturesBuffer[57*128*128*4]
mov ecx, 16*128*128
rep movsd
city_load_done:
ret
LoadCityArrival3D ENDP
HandleCityApproach3D PROC
invoke Pressed3D, 0Dh
test eax, eax
jnz city_approach_complete
mov eax, deltaTime3D
add cityTime3D, eax
city_approach_phase:
mov eax, cityPhase3D
mov ecx, cityDurations3D[eax*4]
cmp cityTime3D, ecx
jb city_approach_done
sub cityTime3D, ecx
cmp cityPhase3D, CITY_DOOR
jae city_approach_complete
inc cityPhase3D
jmp city_approach_phase
city_approach_complete:
mov cityPhase3D, CITY_DOOR
mov cityTime3D, 2800
mov arrivalState3D, ARRIVAL_STOP
mov arrivalTime3D, 0
call ClearKeys3D
city_approach_done:
ret
HandleCityApproach3D ENDP
; Hermite interpolation in 16.16: zero angular velocity at either end of a turn.
CityEase3D PROC uses ebx timeMs:DWORD,durationMs:DWORD
mov eax, timeMs
cmp eax, durationMs
jb @F
mov eax, FP_1
ret
@@:
shl eax, 16
xor edx, edx
div durationMs
mov ebx, eax
imul ebx
shrd eax, edx, 16
shl ebx, 1
mov ecx, 3*FP_1
sub ecx, ebx
imul ecx
shrd eax, edx, 16
ret
CityEase3D ENDP
PositionCityCamera3D PROC uses ebx
mov playerX, (8*FP_1+FP_HALF)
mov playerY, (24*FP_1+FP_HALF)
mov playerAngle, 0
mov viewHorizon3D, 240
mov viewEye3D,CITY_STANDING_EYE
cmp arrivalState3D, ARRIVAL_WALK
jne city_camera_at_door
mov ebx, cityTime3D
cmp cityPhase3D,CITY_STAND
ja city_camera_turn_alley
mov viewEye3D,FP_1*2/5
cmp cityPhase3D, CITY_WAKE
jne city_camera_light
cmp ebx,2800
jb city_camera_done
sub ebx,2800
invoke CityEase3D,ebx,1700
imul eax,80
shr eax, 16
add viewHorizon3D,eax
jmp city_camera_done
city_camera_light:
cmp cityPhase3D,CITY_LIGHT
jne city_camera_smoke
mov viewHorizon3D,320
jmp city_camera_done
city_camera_smoke:
cmp cityPhase3D,CITY_SMOKE
jne city_camera_stand
mov viewHorizon3D,320
invoke CityEase3D,ebx,1200
imul eax,1280
shr eax,16
add viewHorizon3D,eax
jmp city_camera_done
city_camera_stand:
cmp cityPhase3D,CITY_STAND
jne city_camera_done
invoke CityEase3D,ebx,1800
mov ebx,eax
imul eax,CITY_STANDING_EYE-FP_1*2/5
shr eax,16
add viewEye3D,eax
mov eax,ebx
imul eax,1360
shr eax,16
mov viewHorizon3D,1600
sub viewHorizon3D,eax
jmp city_camera_done
city_camera_turn_alley:
cmp cityPhase3D,CITY_LOOK_BIN
jne city_camera_bin_ready
invoke CityEase3D,ebx,CITY_LOOK_BIN_MS
shr eax,9
mov playerAngle,eax
jmp city_camera_done
city_camera_bin_ready:
mov playerAngle,128
cmp cityPhase3D, CITY_TURN_ALLEY
jb city_camera_done
jne city_camera_alley
invoke CityEase3D, ebx, 1200
shr eax, 8
add eax, 128
and eax, 511
mov playerAngle, eax
jmp city_camera_done
city_camera_alley:
mov playerAngle, 384
cmp cityPhase3D, CITY_ALLEY
jne city_camera_turn_street
invoke CityEase3D, ebx, 5400
mov ecx, FP_1*243/20
imul ecx
shrd eax, edx, 16
sub playerY, eax
jmp city_camera_bob
city_camera_turn_street:
mov playerY, (12*FP_1+FP_1*7/20)
cmp cityPhase3D, CITY_TURN_STREET
jne city_camera_street
invoke CityEase3D, ebx, 900
shr eax, 9
add eax, 384
and eax, 511
mov playerAngle, eax
jmp city_camera_done
city_camera_street:
mov playerAngle, 0
cmp cityPhase3D, CITY_STREET
jne city_camera_turn_door
invoke CityEase3D, ebx, 7500
imul eax, 14
add playerX, eax
jmp city_camera_bob
city_camera_turn_door:
mov playerX, (22*FP_1+FP_HALF)
cmp cityPhase3D, CITY_TURN_DOOR
jne city_camera_door_approach
invoke CityEase3D, ebx, 900
shr eax, 9
neg eax
and eax, 511
mov playerAngle, eax
jmp city_camera_done
city_camera_door_approach:
mov playerAngle, 384
invoke CityEase3D, ebx, 2800
mov ecx, FP_1*37/20
imul ecx
shrd eax, edx, 16
sub playerY, eax
jmp city_camera_bob
city_camera_at_door:
mov playerX, (22*FP_1+FP_HALF)
mov playerY, (10*FP_1+FP_HALF)
mov playerAngle, 384
cmp arrivalState3D, ARRIVAL_ENTER
jne city_camera_done
invoke CityEase3D, arrivalTime3D, 1400
sub playerY, eax
jmp city_camera_done
city_camera_bob:
mov eax, cityPhase3D
mov eax, cityDurations3D[eax*4]
sub eax, ebx
cmp eax, ebx
jbe @F
mov eax, ebx
@@:
cmp eax, 500
jbe @F
mov eax, 500
@@:
mov ebx, eax
mov eax, cityClock3D
shr eax, 1
and eax, 511
mov eax, tableCos[eax*4]
imul ebx
mov ecx, 500*16384
idiv ecx
add viewHorizon3D, eax
city_camera_done:
cmp playerY,12*FP_1
jb @F
cmp playerY,13*FP_1
jae @F
add viewEye3D,FP_1*3/50
@@:
ret
PositionCityCamera3D ENDP
DrawCitySky3D PROC uses ebx esi edi
local skyOffset:DWORD
mov eax, cityClock3D
shr eax, 8
mov ecx, playerAngle
shr ecx, 2
add eax, ecx
mov skyOffset, eax
xor esi, esi
lea edi, screenBuffer
city_sky_row:
mov eax, esi
shr eax, 1
mov ebx, eax
and ebx, 127
shl ebx, 7
xor ecx, ecx
city_sky_pixel:
mov eax, ecx
shr eax, 1
add eax, skyOffset
and eax, 255
cmp eax, 127
jbe @F
xor eax, 255
@@:
add eax, ebx
mov eax, texturesBuffer[63*128*128*4+eax*4]
; Four identical destination pixels retain the exact 2x pixel-art sampling.
mov [edi], eax
mov [edi+4], eax
mov [edi+640*4], eax
mov [edi+640*4+4], eax
add edi, 8
inc ecx
cmp ecx, 320
jb city_sky_pixel
inc esi
add edi, 640*4
cmp esi, 240
jb city_sky_row
ret
DrawCitySky3D ENDP
include src_graphics\city_weather.inc
FadeCityFrame3D PROC uses ebx esi amount:DWORD
mov ebx, amount
cmp ebx, 256
jbe @F
mov ebx, 256
@@:
xor esi, esi
city_fade_pixel:
mov eax, screenBuffer[esi*4]
movzx ecx, al
imul ecx, ebx
shr ecx, 8
movzx edx, ah
imul edx, ebx
shr edx, 8
shl edx, 8
or ecx, edx
shr eax, 16
and eax, 255
imul eax, ebx
shr eax, 8
shl eax, 16
or eax, ecx
mov screenBuffer[esi*4], eax
inc esi
cmp esi, SCREEN_SIZE
jb city_fade_pixel
ret
FadeCityFrame3D ENDP
DrawCityCigarette3D PROC uses ebx esi px:DWORD,py:DWORD,angle:DWORD,pixelStep:DWORD
local drawX:DWORD,drawY:DWORD,color:DWORD,u:DWORD,v:DWORD
local lengthPx:DWORD,halfWidth:DWORD,along:DWORD
mov esi, angle
and esi, 511
mov eax, pixelStep
shl eax, 4
mov lengthPx, eax
mov eax, pixelStep
mov halfWidth, eax
mov u, 0
city_cigarette_column:
mov eax, halfWidth
neg eax
mov v, eax
city_cigarette_pixel:
mov eax, v
test eax, eax
jns @F
neg eax
@@:
cmp eax, halfWidth
jne city_cigarette_solid_pixel
cmp u, 2
jb city_cigarette_next_pixel
mov eax, lengthPx
sub eax, 2
cmp u, eax
jae city_cigarette_next_pixel
city_cigarette_solid_pixel:
mov eax, pixelStep
shl eax, 1
mov ebx, u
sub ebx, eax
mov along, ebx
mov eax, ebx
imul tableCos[esi*4]
shrd eax, edx, 16
mov drawX, eax
mov eax, v
imul tableSin[esi*4]
shrd eax, edx, 16
sub drawX, eax
mov eax, drawX
add eax, px
sar eax, 1
mov drawX, eax
mov eax, along
imul tableSin[esi*4]
shrd eax, edx, 16
mov drawY, eax
mov eax, v
imul tableCos[esi*4]
shrd eax, edx, 16
add eax, drawY
add eax, py
sar eax, 1
mov drawY, eax
mov color, 00DDD9C9h
mov eax, pixelStep
shl eax, 2
cmp u, eax
jae city_cigarette_ash
mov color, 00B0783Ch
jmp city_cigarette_shade
city_cigarette_ash:
mov eax, lengthPx
mov ecx, pixelStep
shl ecx, 1
sub eax, ecx
cmp u, eax
jb city_cigarette_shade
mov color, 00746E67h
add eax, pixelStep
cmp u, eax
jb city_cigarette_shade
mov color, 00EC6325h
cmp cityPhase3D,CITY_LIGHT
jne city_cigarette_draw
cmp cityTime3D,900
jae city_cigarette_draw
mov color,00DDD9C9h
jmp city_cigarette_draw
city_cigarette_shade:
mov eax, v
test eax, eax
jns @F
mov eax, color
and eax, 00FEFEFEh
shr eax, 1
add eax, 00484840h
mov color, eax
jmp city_cigarette_draw
@@:
cmp eax, halfWidth
jl city_cigarette_draw
mov eax, color
and eax, 00FEFEFEh
shr eax, 1
mov color, eax
city_cigarette_draw:
invoke DrawBox, drawX, drawY, 1, 1, color
city_cigarette_next_pixel:
inc v
mov eax, v
cmp eax, halfWidth
jle city_cigarette_pixel
inc u
mov eax, u
cmp eax, lengthPx
jb city_cigarette_column
ret
DrawCityCigarette3D ENDP
DrawCityCigaretteSmoke3D PROC uses ebx esi edi tipX:DWORD,tipY:DWORD
local left:DWORD,top:DWORD
mov eax, cityClock3D
xor edx, edx
mov ecx, 180
div ecx
and eax, 3
mov esi, eax
mov eax, citySmokeRootX3D[esi*4]
imul eax, 180
xor edx, edx
mov ecx, 96
div ecx
mov ebx, tipX
sub ebx, eax
mov left, ebx
mov eax, citySmokeRootY3D[esi*4]
imul eax, 280
xor edx, edx
mov ecx, 128
div ecx
mov edi, tipY
sub edi, eax
mov top, edi
mov animOpacity3D, 245
invoke DrawAnimSprite3D, OFFSET citySmokePack3D, esi, left, top, 180, 280
mov ebx, tipX
sub ebx, 64
mov edi, tipY
sub edi, 290
mov animOpacity3D, 105
invoke DrawAnimSprite3D, OFFSET cityCloudPack3D, esi, ebx, edi, 128, 180
mov animOpacity3D, 255
ret
DrawCityCigaretteSmoke3D ENDP
DrawCitySmokingHand3D PROC uses ebx esi edi
local pose:DWORD,pinchX:DWORD,pinchY:DWORD,offsetY:DWORD,part:AnimPack3D
local anchorX:DWORD,anchorY:DWORD
cmp cityHandsPack3D.pixels, 0
je city_hand_done
mov pose, 5
mov pinchX, 500
mov pinchY, 310
mov offsetY, 0
cmp cityPhase3D,CITY_LIGHT
jne city_hand_sky_lower
invoke CityEase3D,cityTime3D,600
neg eax
add eax,FP_1
imul eax,110
shr eax,16
mov offsetY,eax
jmp city_hand_toss
city_hand_sky_lower:
cmp cityPhase3D,CITY_SMOKE
jne city_hand_rising
invoke CityEase3D,cityTime3D,900
imul eax,240
shr eax,16
mov offsetY,eax
jmp city_hand_toss
city_hand_rising:
cmp cityPhase3D,CITY_STAND
jne city_hand_toss
invoke CityEase3D,cityTime3D,1800
neg eax
add eax,FP_1
imul eax,240
shr eax,16
mov offsetY,eax
jmp city_hand_toss
cmp cityPhase3D, CITY_WAKE
jne city_hand_toss
mov eax, 3100
sub eax, cityTime3D
imul eax, 480
xor edx, edx
mov ecx, 1300
div ecx
mov offsetY, eax
city_hand_toss:
cmp cityPhase3D, CITY_TOSS
jne city_hand_breath
mov eax, cityTime3D
cmp eax, 750
jae city_hand_release_pose
imul eax, 3
xor edx, edx
mov ecx, 750
div ecx
add eax, 5
jmp city_hand_store_pose
city_hand_release_pose:
mov eax, 8
cmp cityTime3D, 900
jb city_hand_store_pose
mov eax, cityTime3D
sub eax, 900
imul eax, 7
xor edx, edx
mov ecx, 600
div ecx
add eax, 9
city_hand_store_pose:
cmp eax, 15
jbe @F
mov eax, 15
@@:
mov pose, eax
invoke CityEase3D, cityTime3D, 750
mov ebx, eax
imul eax, 80
shr eax, 16
sub pinchX, eax
mov eax, ebx
imul eax, 30
shr eax, 16
sub pinchY, eax
cmp cityTime3D, 1000
jb city_hand_position
mov eax, cityTime3D
sub eax, 1000
invoke CityEase3D, eax, 500
imul eax, 300
shr eax, 16
add offsetY, eax
jmp city_hand_position
city_hand_breath:
mov eax, cityClock3D
shr eax, 3
and eax, 511
mov eax, tableCos[eax*4]
sar eax, 14
add pinchY, eax
city_hand_position:
mov ebx, pose
mov eax, cityFingerX3D[ebx*4]
mov anchorX, eax
mov eax, cityFingerY3D[ebx*4]
mov anchorY, eax
cmp cityPhase3D, CITY_TOSS
jne city_hand_project_anchor
cmp cityTime3D, 750
jb city_hand_project_anchor
cmp cityTime3D, 900
jae city_hand_project_anchor
; Preserve the grip location while the fingers first open, instead of jumping the wrist.
mov eax, cityTime3D
sub eax, 750
invoke CityEase3D, eax, 150
mov edi, eax
imul eax, 10
shr eax, 16
neg eax
add eax, 110
mov anchorX, eax
mov eax, edi
imul eax, 42
shr eax, 16
add eax, 27
mov anchorY, eax
city_hand_project_anchor:
mov eax, anchorX
imul eax, 360
xor edx, edx
mov ecx, 256
div ecx
mov edx, pinchX
sub edx, eax
mov cityHandX3D, edx
mov eax, anchorY
imul eax, 270
xor edx, edx
mov ecx, 192
div ecx
mov edx, pinchY
sub edx, eax
add edx, offsetY
mov cityHandY3D, edx
cmp cityPhase3D, CITY_TOSS
jne city_hand_draw_held
cmp cityTime3D, 750
jae city_hand_draw_sprite
city_hand_draw_held:
mov eax, pinchX
mov cityCigaretteX3D, eax
mov eax, pinchY
add eax, offsetY
mov cityCigaretteY3D, eax
mov eax, tableCos[320*4]
imul eax, 55
sar eax, 16
add eax, cityCigaretteX3D
mov ebx, eax
mov eax, tableSin[320*4]
imul eax, 55
sar eax, 16
add eax, cityCigaretteY3D
cmp cityPhase3D,CITY_LIGHT
jne city_hand_tip_smoke
cmp cityTime3D,1000
jb city_hand_unlit
city_hand_tip_smoke:
invoke DrawCityCigaretteSmoke3D, ebx, eax
city_hand_unlit:
invoke DrawCityCigarette3D, cityCigaretteX3D, cityCigaretteY3D, 320, 4
city_hand_draw_sprite:
; The opaque fingers cover the filter, with the paper extending out of the grip.
invoke DrawAnimSprite3D, OFFSET cityHandsPack3D, pose, cityHandX3D, cityHandY3D, 360, 270
; Continue only the sleeve's bottom rows, never a translucent full-screen matte.
mov eax, cityHandY3D
add eax, 270
cmp eax, 480
jae city_hand_cigarette
mov edi, eax
mov esi, 480
sub esi, eax
mov part.imageWidth, 256
mov part.height, 8
mov part.frames, 1
mov eax, pose
imul eax, 256*192*4
add eax, cityHandsPack3D.pixels
add eax, 256*184*4
mov part.pixels, eax
invoke DrawAnimSprite3D, ADDR part, 0, cityHandX3D, edi, 360, esi
city_hand_cigarette:
cmp cityPhase3D, CITY_TOSS
jne city_hand_done
cmp cityTime3D, 750
jae city_hand_flight
ret
city_hand_flight:
cmp cityTime3D, 1200
jae city_hand_done
; Independent ballistic screen-space arc terminates inside the projected bin mouth.
mov eax, cityTime3D
sub eax, 750
shl eax, 16
xor edx, edx
mov ecx, 450
div ecx
mov ebx, eax
mov eax, cityMouthX3D
sub eax, 420
imul ebx
shrd eax, edx, 16
add eax, 420
mov cityCigaretteX3D, eax
mov eax, cityMouthY3D
sub eax, 280
imul ebx
shrd eax, edx, 16
add eax, 280
mov cityCigaretteY3D, eax
mov eax, FP_1
sub eax, ebx
imul ebx
shrd eax, edx, 16
imul eax, 180
shr eax, 16
sub cityCigaretteY3D, eax
mov eax, cityTime3D
sub eax, 750
imul eax, 2
add eax, 320
mov ebx, 4
cmp cityTime3D, 900
jb @F
dec ebx
cmp cityTime3D, 1050
jb @F
dec ebx
cmp cityTime3D, 1125
jb @F
dec ebx
@@:
invoke DrawCityCigarette3D, cityCigaretteX3D, cityCigaretteY3D, eax, ebx
call DrawCityBinBodies3D
city_hand_done:
ret
DrawCitySmokingHand3D ENDP
DrawCityExhaledSmoke3D PROC uses ebx esi edi
mov esi, cityTime3D
sub esi,600
js city_exhale_done
cmp esi, 2300
jae city_exhale_done
mov eax, esi
xor edx, edx
mov ecx, 600
div ecx
cmp eax, 3
jbe @F
mov eax, 3
@@:
mov ebx, eax
mov animOpacity3D, 155
cmp esi, 300
jae city_exhale_fade
mov eax, esi
imul eax, 155
xor edx, edx
mov ecx, 300
div ecx
mov animOpacity3D, eax
city_exhale_fade:
cmp esi, 1500
jb city_exhale_draw
mov eax, 2300
sub eax, esi
imul eax, 155
xor edx, edx
mov ecx, 800
div ecx
mov animOpacity3D, eax
city_exhale_draw:
mov eax, esi
xor edx, edx
mov ecx, 7
div ecx
mov edi, 285
sub edi, eax
invoke DrawAnimSprite3D, OFFSET cityCloudPack3D, ebx, 175, edi, 360, 400
mov eax, esi
xor edx, edx
mov ecx, 6
div ecx
mov edi, 355
sub edi, eax
invoke DrawAnimSprite3D, OFFSET cityCloudPack3D, ebx, 335, edi, 250, 310
mov animOpacity3D, 255
city_exhale_done:
ret
DrawCityExhaledSmoke3D ENDP
include src_graphics\city_wake_scene.inc
RenderCityArrival3D PROC uses ebx esi edi
local savedX:DWORD,savedY:DWORD,savedAngle:DWORD,savedMap:DWORD
local savedHorizon:DWORD,savedFloor:DWORD,savedOutdoor:DWORD,savedEye:DWORD,bar:DWORD
local skyBlend:DWORD
cmp arrivalState3D, ARRIVAL_WALK
jne @F
cmp cityPhase3D, CITY_BLACK
jne @F
invoke DrawBox, 0, 0, 320, 240, 0
ret
@@:
mov eax, playerX
mov savedX, eax
mov eax, playerY
mov savedY, eax
mov eax, playerAngle
mov savedAngle, eax
mov eax, worldMap3D
mov savedMap, eax
mov eax, viewHorizon3D
mov savedHorizon, eax
mov eax, floorTexture3D
mov savedFloor, eax
mov eax, outdoorRender3D
mov savedOutdoor, eax
mov eax, viewEye3D
mov savedEye, eax
call PositionCityCamera3D
mov worldMap3D, OFFSET cityMap3D
mov floorTexture3D, 60
mov outdoorRender3D, 1
call UpdateCamera3D
call DrawCitySky3D
mov skyBlend,0
cmp arrivalState3D, ARRIVAL_WALK
jne city_render_world
cmp cityPhase3D,CITY_SMOKE
jne city_render_stand_sky
mov eax,cityTime3D
sub eax,550
js city_render_world
invoke CityEase3D,eax,650
shr eax,8
mov skyBlend,eax
jmp city_render_capture_sky
city_render_stand_sky:
cmp cityPhase3D,CITY_STAND
jne city_render_world
invoke CityEase3D,cityTime3D,900
shr eax,8
neg eax
add eax,256
mov skyBlend,eax
city_render_capture_sky:
cmp skyBlend,256
je city_render_sky_smoke
lea esi,screenBuffer
lea edi,citySkyBuffer3D
mov ecx,SCREEN_SIZE
rep movsd
city_render_world:
call RenderCeilingAndFloor
call DrawCitySkyline3D
call RenderWalls
call PrepareCityDepth3D
call RenderStreetDressing3D
call RenderCityObjects3D
call RenderCityFurniture3D
call RenderCityBins3D
call RenderCityAlley3D
call RenderCityFacade3D
call RenderCityGuards3D
cmp arrivalState3D,ARRIVAL_WALK
jne @F
call DrawCityWakeActor3D
@@:
cmp skyBlend,0
je @F
invoke BlendCitySky3D,skyBlend
@@:
call DrawCityRain3D
cmp arrivalState3D, ARRIVAL_WALK
jne city_render_restore
cmp cityPhase3D, CITY_TOSS
ja city_render_restore
call DrawCitySeatedLegs3D
cmp cityPhase3D, CITY_WAKE
jne @F
call DrawCityWakeSubtitle3D
jmp city_wake_eye_mask
@@:
call DrawCityLighter3D
call DrawCitySmokingHand3D
cmp cityPhase3D,CITY_SMOKE
jne city_render_restore
call DrawCityExhaledSmoke3D
jmp city_render_restore
city_render_sky_smoke:
call DrawCityRain3D
cmp cityPhase3D,CITY_SMOKE
jne city_render_restore
call DrawCitySmokingHand3D
call DrawCityExhaledSmoke3D
jmp city_render_restore
city_wake_eye_mask:
mov eax, cityTime3D
cmp eax, 900
jae city_wake_blink
imul eax, 240
xor edx, edx
mov ecx, 900
div ecx
neg eax
add eax, 240
jmp city_wake_bars
city_wake_blink:
cmp eax, 1120
jae city_wake_reopen
sub eax, 900
imul eax, 120
xor edx, edx
mov ecx, 220
div ecx
jmp city_wake_bars
city_wake_reopen:
cmp eax, 1380
jae city_render_restore
sub eax, 1120
imul eax, 120
xor edx, edx
mov ecx, 260
div ecx
neg eax
add eax, 120
city_wake_bars:
shr eax, 1
mov bar, eax
invoke DrawBox, 0, 0, 320, bar, 0
mov eax, 240
sub eax, bar
invoke DrawBox, 0, eax, 320, bar, 0
city_render_restore:
mov eax, savedX
mov playerX, eax
mov eax, savedY
mov playerY, eax
mov eax, savedAngle
mov playerAngle, eax
mov eax, savedMap
mov worldMap3D, eax
mov eax, savedHorizon
mov viewHorizon3D, eax
mov eax, savedFloor
mov floorTexture3D, eax
mov eax, savedOutdoor
mov outdoorRender3D, eax
mov eax, savedEye
mov viewEye3D, eax
call UpdateCamera3D
ret
RenderCityArrival3D ENDP
RenderArrival3D PROC uses ebx esi edi
local guardFrame:DWORD,guardW:DWORD,guardH:DWORD,guardY:DWORD,leftX:DWORD,rightX:DWORD
call RenderCityArrival3D
cmp arrivalState3D, ARRIVAL_PROFILE
jne city_arrival_name
call DrawEntryProfileRows3D
ret
city_arrival_name:
cmp arrivalState3D, ARRIVAL_NAME
jne city_arrival_fade
invoke DrawBoxBorder, 172, 65, 140, 117, 0017191Ch, 00BD985Ah, 1
invoke DrawString8x8, 180, 74, OFFSET entryNameText3D, 00F0D7ABh
invoke DrawBoxBorder, 177, 92, 130, 22, 002D3934h, 00B6D9B4h, 1
invoke DrawString8x8, 180, 99, OFFSET arrivalName3D, 00FFFFFFh
invoke DrawString8x8, 180, 124, OFFSET entryNameHint3D, 00BCC6BAh
invoke DrawString8x8, 180, 161, OFFSET entryCancel3D, 00BCC6BAh
invoke DrawString8x8, 263, 161, OFFSET entryConfirm3D, 00F0D7ABh
cmp arrivalError3D, 0
je city_arrival_done
invoke DrawString8x8, 180, 143, OFFSET entryNameError3D, 00EC8875h
ret
city_arrival_fade:
cmp arrivalState3D, ARRIVAL_ENTER
jne city_arrival_done
cmp arrivalTime3D, 1000
jb city_arrival_done
mov eax, arrivalTime3D
cmp eax, 1400
jbe @F
mov eax, 1400
@@:
sub eax, 1000
shl eax, 8
xor edx, edx
mov ecx, 400
div ecx
neg eax
add eax, 256
invoke FadeCityFrame3D, eax
city_arrival_done:
ret
RenderArrival3D ENDP