Add native Durak, poker, blackjack, roulette, Buckshot and billiards scenes with animation assets and regression tests. Improve arrival, city, hall, profiles, shops, audio and exit handling; remove the portable C game core and refresh shipping executables.
899 lines
21 KiB
PHP
899 lines
21 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_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 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, 128
|
|
mov viewHorizon3D, 240
|
|
cmp arrivalState3D, ARRIVAL_WALK
|
|
jne city_camera_at_door
|
|
mov ebx, cityTime3D
|
|
cmp cityPhase3D, CITY_WAKE
|
|
jne city_camera_turn_alley
|
|
mov viewHorizon3D, 1600
|
|
cmp ebx, 1800
|
|
jb city_camera_done
|
|
sub ebx, 1800
|
|
invoke CityEase3D, ebx, 1300
|
|
imul eax, 1360
|
|
shr eax, 16
|
|
sub viewHorizon3D, eax
|
|
jmp city_camera_done
|
|
city_camera_turn_alley:
|
|
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:
|
|
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
|
|
|
|
DrawCityRain3D PROC uses ebx esi
|
|
xor esi, esi
|
|
city_rain_drop:
|
|
mov eax, esi
|
|
imul eax, 137
|
|
mov ebx, cityClock3D
|
|
shr ebx, 4
|
|
sub eax, ebx
|
|
and eax, 511
|
|
imul eax, 5
|
|
shr eax, 3
|
|
mov ebx, eax
|
|
mov eax, cityClock3D
|
|
shr eax, 2
|
|
mov ecx, esi
|
|
imul ecx, 83
|
|
add eax, ecx
|
|
xor edx, edx
|
|
mov ecx, 240
|
|
div ecx
|
|
invoke DrawBox, ebx, edx, 1, 4, 00395468h
|
|
inc esi
|
|
cmp esi, 70
|
|
jb city_rain_drop
|
|
ret
|
|
DrawCityRain3D ENDP
|
|
|
|
|
|
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
|
|
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_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
|
|
invoke DrawCityCigaretteSmoke3D, ebx, eax
|
|
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
|
|
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
|
|
|
|
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
|
|
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
|
|
mov viewEye3D, FP_1*17/20
|
|
call UpdateCamera3D
|
|
call DrawCitySky3D
|
|
cmp arrivalState3D, ARRIVAL_WALK
|
|
jne city_render_world
|
|
cmp cityPhase3D, CITY_WAKE
|
|
jne city_render_world
|
|
cmp cityTime3D, 1800
|
|
jb city_render_sky_smoke
|
|
city_render_world:
|
|
call RenderCeilingAndFloor
|
|
call DrawCitySkyline3D
|
|
call RenderWalls
|
|
call PrepareCityDepth3D
|
|
call RenderCityObjects3D
|
|
call RenderCityFurniture3D
|
|
call RenderCityBins3D
|
|
call RenderCityFacade3D
|
|
call RenderCityGuards3D
|
|
call DrawCityRain3D
|
|
cmp arrivalState3D, ARRIVAL_WALK
|
|
jne city_render_restore
|
|
cmp cityPhase3D, CITY_TOSS
|
|
ja city_render_restore
|
|
cmp cityPhase3D, CITY_WAKE
|
|
jne @F
|
|
call DrawCityExhaledSmoke3D
|
|
@@:
|
|
call DrawCitySmokingHand3D
|
|
cmp cityPhase3D, CITY_WAKE
|
|
jne city_render_restore
|
|
jmp city_wake_eye_mask
|
|
city_render_sky_smoke:
|
|
call DrawCityRain3D
|
|
call DrawCityExhaledSmoke3D
|
|
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
|