KAZIK/tools/tests/world_regression.inc
Artvasil09 3ad5bf4c9d Develop assembly-only casino scenes and native games
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.
2026-10-08 22:39:19 +03:00

330 lines
8.1 KiB
PHP

include tools\tests\street_population_test.inc
RunWorldRegression3D PROC uses ebx esi edi
local clock:DWORD,phase:DWORD,sample:DWORD,rounds:DWORD
local floorRow:DWORD
call InitHall3D
mov hallTestStage3D,7701
cmp hallStreetLife3D.frames, 40
jne world_test_fail
; Serving from every front segment is allowed; staff side never targets the bar.
mov playerAngle, 384
mov esi, 3
world_bar_front:
mov eax, esi
shl eax, 16
add eax, FP_HALF
mov playerX, eax
mov playerY,24*FP_1+FP_1/4
call UpdateCamera3D
mov interactTargetId, 0
call CheckHallInteractions3D
cmp interactTargetId, INTERACT_BAR
jne world_test_fail
invoke CanWalk3D,playerX,playerY
cmp eax, 1
jne world_test_fail
inc esi
cmp esi, 9
jb world_bar_front
mov playerY,22*FP_1+FP_HALF
mov interactTargetId,0
call CheckHallInteractions3D
cmp interactTargetId, INTERACT_BAR
je world_test_fail
invoke CanWalk3D,16*FP_1,4*FP_1
test eax, eax
jnz world_test_fail
invoke CanWalk3D,16*FP_1,5*FP_1+FP_HALF
cmp eax,1
jne world_test_fail
mov hallTestStage3D,7702
; Validate standing/seated visitors against the actual map, not an illustration.
xor esi,esi
world_guest_cell:
cmp esi,8
jb @F
cmp esi,12
jb world_guest_next
@@:
imul ebx,esi,SIZEOF CityProp3D
mov eax,hallGuests3D[ebx].posX
sar eax,16
mov ecx,hallGuests3D[ebx].posY
sar ecx,16
shl ecx,5
add eax,ecx
cmp casinoMap[eax],0
jne world_test_fail
world_guest_next:
inc esi
cmp esi,HALL_PATRON_COUNT
jb world_guest_cell
mov hallTestStage3D,7703
; Sample the complete camera path against road vehicle footprints.
mov arrivalState3D,ARRIVAL_WALK
mov clock,0
mov phase,0
world_route_phase:
mov eax,phase
mov cityPhase3D,eax
mov sample,0
world_route_sample:
mov eax,sample
mov cityTime3D,eax
mov eax,clock
mov cityClock3D,eax
call PositionCityCamera3D
call AnimateCityCars3D
call AnimateCityPedestrians3D
mov eax,playerX
sar eax,16
mov ecx,playerY
sar ecx,16
shl ecx,5
add eax,ecx
cmp cityMap3D[eax],0
jne world_test_fail
mov esi,CITY_FIRST_CAR
world_route_car:
cmp esi,12
je world_route_car_next
cmp esi,13
je world_route_car_next
imul ebx,esi,SIZEOF CityProp3D
mov eax,playerX
sub eax,cityObjects3D[ebx].posX
test eax,eax
jns @F
neg eax
@@:
cmp eax,FP_1*17/10
ja world_route_car_next
mov eax,playerY
sub eax,cityObjects3D[ebx].posY
test eax,eax
jns @F
neg eax
@@:
cmp eax,FP_1*4/5
jb world_test_fail
world_route_car_next:
inc esi
cmp esi,CITY_TRAFFIC_WEST+1
jb world_route_car
add clock,50
add sample,50
mov ecx,phase
mov eax,cityDurations3D[ecx*4]
cmp sample,eax
jb world_route_sample
inc phase
cmp phase,10
jb world_route_phase
mov cityPhase3D,CITY_STREET
mov cityTime3D,3100
call RenderCityArrival3D
invoke WriteActionSnapshot3D,OFFSET hallTestStreetV43D
call RunStreetPopulationTest3D
test eax,eax
jz world_test_fail
; Taller storeys must not sink the wall base below the actual ground plane.
mov hallTestStage3D,7707
mov worldMap3D,OFFSET cityMap3D
mov outdoorRender3D,1
mov playerX,14*FP_1+FP_HALF
mov playerY,14*FP_1+FP_HALF
mov playerAngle,384
call UpdateCamera3D
lea edi,screenBuffer
mov eax,0DEADBEEFh
mov ecx,SCREEN_SIZE
rep stosd
call RenderWalls
mov eax,viewEye3D
imul eax,SCREEN_H
cdq
idiv zBuffer[HALF_W*4]
add eax,viewHorizon3D
mov floorRow,eax
add eax,3
imul eax,SCREEN_W
cmp screenBuffer[eax*4+HALF_W*4],0DEADBEEFh
jne world_test_fail
mov eax,floorRow
sub eax,3
imul eax,SCREEN_W
cmp screenBuffer[eax*4+HALF_W*4],0DEADBEEFh
je world_test_fail
mov worldMap3D,OFFSET casinoMap
mov outdoorRender3D,0
mov playerX,16*FP_1
mov playerY,8*FP_1+FP_1/5
mov playerAngle,384
call UpdateCamera3D
call RenderCeilingAndFloor
call RenderWalls
call PrepareCityDepth3D
call RenderSprites
call RenderHall3D
invoke WriteActionSnapshot3D,OFFSET hallTestCabaret3D
mov barPhase3D,2
mov barTime3D,1100
mov barSelection3D,0
call RenderBar3D
invoke WriteActionSnapshot3D,OFFSET hallTestHighball3D
mov barSelection3D,1
call RenderBar3D
invoke WriteActionSnapshot3D,OFFSET hallTestCocktail3D
mov barSelection3D,2
call RenderBar3D
invoke WriteActionSnapshot3D,OFFSET hallTestWater3D
mov barPhase3D,0
mov hallTestStage3D,7704
; A ball on cloth just outside the visible mouth must not vanish.
call InitPool3D
mov poolX3D,38*FP_1
mov poolY3D,58*FP_1
invoke PoolPocketBall3D,0
cmp poolActive3D,1
jne world_test_fail
; All six throats are reached through motion, not direct state manipulation.
xor esi,esi
world_pocket_motion:
call InitPool3D
mov edi,1
world_pocket_clear:
mov poolActive3D[edi*4],0
inc edi
cmp edi,16
jb world_pocket_clear
mov eax,poolPocketX3D[esi*4]
mov poolX3D,eax
mov eax,poolPocketY3D[esi*4]
mov poolY3D,eax
mov poolVY3D,-50000
mov eax,esi
xor edx,edx
mov ecx,3
div ecx
cmp edx,1
je world_pocket_y
mov poolVY3D,-35000
cmp edx,0
jne world_pocket_right
add poolX3D,12*FP_1
mov poolVX3D,-35000
jmp world_pocket_y
world_pocket_right:
sub poolX3D,12*FP_1
mov poolVX3D,35000
world_pocket_y:
cmp esi,3
jae world_pocket_bottom
add poolY3D,12*FP_1
jmp world_pocket_steps
world_pocket_bottom:
sub poolY3D,12*FP_1
neg poolVY3D
world_pocket_steps:
mov ebx,60
world_pocket_tick:
call PoolStep3D
dec ebx
jnz world_pocket_tick
cmp poolActive3D,0
jne world_test_fail
cmp poolPocket3D,esi
jne world_test_fail
inc esi
cmp esi,6
jb world_pocket_motion
call PoolFinishShot3D
cmp poolState3D,POOL_HAND
jne world_test_fail
call RenderPool3D
invoke WriteActionSnapshot3D,OFFSET hallTestScratch3D
invoke PoolPlaceCue3D,82*FP_1,115*FP_1
cmp eax,1
jne world_test_fail
cmp poolActive3D,1
jne world_test_fail
mov hallTestStage3D,7705
; Mouse button and slider call real handler paths; Space uses the chosen force.
call ClearKeys3D
mov poolPlayer3D,0
mov poolState3D,POOL_AIM
mov mouseClick3D,1
mov mouseX3D,255
mov mouseY3D,201
call HandlePool3D
cmp poolPower3D,49000
jne world_test_fail
mov mouseClick3D,0
mov pressedKeys3D[20h],1
call HandlePool3D
cmp poolState3D,POOL_STRIKE
jne world_test_fail
mov deltaTime3D,240
call HandlePool3D
cmp poolVX3D,49000
jne world_test_fail
mov hallTestStage3D,7706
; Stress high/low-power breaks: active balls stay inside the table,
; inactive balls must name a real pocket. No silent deletion or runaway.
mov rounds,0
world_break_round:
call InitPool3D
mov eax,rounds
imul eax,37
and eax,511
mov poolAngle3D,eax
mov eax,rounds
imul eax,821
add eax,8000
mov poolPower3D,eax
call PoolShoot3D
mov deltaTime3D,240
call HandlePool3D
mov ebx,6000
world_break_step:
call PoolStep3D
xor esi,esi
world_break_bounds:
cmp poolActive3D[esi*4],0
je world_break_inactive
cmp poolX3D[esi*4],26*FP_1
jl world_test_fail
cmp poolX3D[esi*4],294*FP_1
jg world_test_fail
cmp poolY3D[esi*4],46*FP_1
jl world_test_fail
cmp poolY3D[esi*4],184*FP_1
jg world_test_fail
jmp world_break_next
world_break_inactive:
cmp poolPocket3D[esi*4],5
ja world_test_fail
world_break_next:
inc esi
cmp esi,16
jb world_break_bounds
cmp poolStill3D,1
je world_break_finished
dec ebx
jnz world_break_step
jmp world_test_fail
world_break_finished:
inc rounds
cmp rounds,100
jb world_break_round
call InitPool3D
mov poolPower3D,49000
call RenderPool3D
invoke WriteActionSnapshot3D,OFFSET hallTestPower3D
mov mouseClick3D,0
mov eax,1
ret
world_test_fail:
xor eax,eax
ret
RunWorldRegression3D ENDP