KAZIK/tools/tests/hall_expansion_test.inc
Artvasil09 797ee366dc feat: implement upper lounge, manual stairs, cabaret, and casino terminals
- 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
2026-10-18 21:36:12 +03:00

598 lines
18 KiB
PHP

.data
expansionStage dd 1
expansionOcclusionPixel dd 0
expansionBmpHeader db 42h,4Dh
dd 1228854
dw 0,0
dd 54,40,640,-480
dw 1,32
dd 0,1228800,0,0,0,0
expansionDoor db "build\hall-expansion\basement-door.bmp",0
expansionStairs db "build\hall-expansion\upper-stairs.bmp",0
expansionStairsMid db "build\hall-expansion\upper-stairs-mid.bmp",0
expansionUpper db "build\hall-expansion\upper-lounge.bmp",0
expansionUpperBar db "build\hall-expansion\upper-bar.bmp",0
expansionJazz db "build\hall-expansion\cabaret-jazz.bmp",0
expansionJazz1 db "build\hall-expansion\cabaret-jazz-1.bmp",0
expansionJazz2 db "build\hall-expansion\cabaret-jazz-2.bmp",0
expansionJazz3 db "build\hall-expansion\cabaret-jazz-3.bmp",0
expansionChorus db "build\hall-expansion\cabaret-chorus.bmp",0
expansionCast db "build\hall-expansion\guest-cast.bmp",0
expansionUpEntry db "build\hall-expansion\upper-entrance-open.bmp",0
expansionUpReturn db "build\hall-expansion\upper-stair-return.bmp",0
expansionUpLanding db "build\hall-expansion\upper-landing-open.bmp",0
expansionUpExit db "build\hall-expansion\upper-exit-open.bmp",0
expansionDownClosed db "build\hall-expansion\old-basement-closed.bmp",0
expansionDownReturn db "build\hall-expansion\basement-stair-return.bmp",0
expansionDownLanding db "build\hall-expansion\basement-landing-open.bmp",0
expansionBunkerReturn db "build\hall-expansion\bunker-return-open.bmp",0
expansionPortalClosed db "build\hall-expansion\portal-closed.bmp",0
expansionBuckshotTable db "build\hall-expansion\upper-buckshot-table.bmp",0
expansionRussianTable db "build\hall-expansion\upper-russian-table.bmp",0
expansionBarWorld db "build\hall-expansion\upper-bar-world.bmp",0
expansionSeating db "build\hall-expansion\upper-seating.bmp",0
expansionLeverMid db "build\hall-expansion\lever-mid-pull.bmp",0
expansionPortal0 db "build\hall-expansion\portal-00.bmp",0
expansionPortal1 db "build\hall-expansion\portal-01.bmp",0
expansionPortal2 db "build\hall-expansion\portal-02.bmp",0
expansionPortal3 db "build\hall-expansion\portal-03.bmp",0
expansionPortal4 db "build\hall-expansion\portal-04.bmp",0
expansionPortal5 db "build\hall-expansion\portal-05.bmp",0
expansionPortal6 db "build\hall-expansion\portal-06.bmp",0
expansionPortal7 db "build\hall-expansion\portal-07.bmp",0
expansionPortal8 db "build\hall-expansion\portal-08.bmp",0
expansionPortal9 db "build\hall-expansion\portal-09.bmp",0
expansionPortal10 db "build\hall-expansion\portal-10.bmp",0
expansionPortal11 db "build\hall-expansion\portal-11.bmp",0
expansionPortalPaths dd OFFSET expansionPortal0,OFFSET expansionPortal1,OFFSET expansionPortal2,OFFSET expansionPortal3,OFFSET expansionPortal4,OFFSET expansionPortal5
dd OFFSET expansionPortal6,OFFSET expansionPortal7,OFFSET expansionPortal8,OFFSET expansionPortal9,OFFSET expansionPortal10,OFFSET expansionPortal11
.data?
expansionSinglePixels dd SCREEN_SIZE dup(?)
.code
ExpansionSnapshot PROC uses ebx path:DWORD
local count:DWORD
invoke CreateFileA,path,40000000h,0,0,2,80h,0
cmp eax,-1
je expansion_snapshot_fail
mov ebx,eax
invoke WriteFile,ebx,OFFSET expansionBmpHeader,54,ADDR count,0
invoke WriteFile,ebx,OFFSET screenBuffer,1228800,ADDR count,0
invoke CloseHandle,ebx
ret
expansion_snapshot_fail:
invoke ExitProcess,99
ret
ExpansionSnapshot ENDP
ExpansionFrame PROC
call UpdateCamera3D
call RenderCeilingAndFloor
call RenderWalls
call PrepareCityDepth3D
call RenderSprites
call RenderHall3D
ret
ExpansionFrame ENDP
ExpansionWalkFrame PROC
add animationClock3D,16
call UpdateInteriorTravel3D
call HandlePlayerInput
call UpdateInteriorTravel3D
call UpdateInteriorEye3D
ret
ExpansionWalkFrame ENDP
ExpansionPortalSnapshot PROC path:DWORD
call UpdateInteriorEye3D
call ExpansionFrame
cmp portalPixelsWritten3D,1000
jae @F
invoke ExitProcess,expansionStage
@@:
invoke ExpansionSnapshot,path
ret
ExpansionPortalSnapshot ENDP
ExpansionTestStart PROC
call InitPaths3D
call LoadTextures3D
call InitializeCasinoSprites3D
call InitHall3D
call LoadHallAssets3D
cmp npcGuestArt3D.pixels,0
je expansion_fail
cmp cabaretArt3D.pixels,0
je expansion_fail
cmp cabaretPianoArt3D.pixels,0
je expansion_fail
cmp cabaretGuitarArt3D.pixels,0
je expansion_fail
cmp upperPortalArt3D.frames,13
jne expansion_fail
cmp upperLeverArt3D.frames,6
jne expansion_fail
cmp upperBrazierArt3D.frames,4
jne expansion_fail
cmp scrStation3D.posX,29*FP_1
jne expansion_fail
cmp scrStation3D.posY,FP_1*15/2
jne expansion_fail
cmp upperFeltPixels3D[0],0FF1B5039h
jb expansion_fail
cmp upperKeyPixels3D[0],80000000h
jb expansion_fail
mov deltaTime3D,16
mov engineMode,MODE_WALK
mov hallLevel3D,0
mov expansionStage,2
invoke CanWalk3D,FP_1*285/10,FP_1*105/10
test eax,eax
jnz expansion_fail
mov interactTargetId,INTERACT_BASEMENT
call TriggerHallInteraction3D
cmp engineMode,MODE_WALK
jne expansion_fail
cmp basementDoorTarget3D,FP_1
jne expansion_fail
xor esi,esi
expansion_open_door:
add animationClock3D,16
call UpdateInteriorTravel3D
inc esi
cmp esi,60
jb expansion_open_door
cmp basementDoorOpen3D,FP_1
jne expansion_fail
invoke CanWalk3D,FP_1*285/10,FP_1*105/10
cmp eax,1
jne expansion_fail
mov playerX,27*FP_1
mov playerY,FP_1*105/10
mov playerAngle,0
call UpdateInteriorEye3D
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionDoor
mov expansionStage,3
mov keys3D[57h],1
xor esi,esi
expansion_down:
cmp engineMode,MODE_STAIRS
jne @F
cmp playerX,FP_1*165/10
jb @F
mov playerAngle,384
@@:
call ExpansionWalkFrame
cmp engineMode,MODE_WALK
jne @F
cmp hallLevel3D,1
je expansion_at_bunker
@@:
inc esi
cmp esi,800
jb expansion_down
jmp expansion_fail
expansion_at_bunker:
mov keys3D[57h],0
cmp playerAngle,384
jne expansion_fail
cmp worldMap3D,OFFSET bunkerMap3D
jne expansion_fail
mov expansionStage,4
mov playerAngle,128
mov keys3D[57h],1
xor esi,esi
expansion_up_basement:
cmp engineMode,MODE_STAIRS
jne @F
cmp playerY,21*FP_1
jb @F
mov playerAngle,256
@@:
call ExpansionWalkFrame
cmp engineMode,MODE_WALK
jne @F
cmp hallLevel3D,0
je expansion_back_hall
@@:
inc esi
cmp esi,800
jb expansion_up_basement
jmp expansion_fail
expansion_back_hall:
mov keys3D[57h],0
cmp playerX,28*FP_1-FP_1/10
jb expansion_fail
cmp playerX,FP_1*282/10
ja expansion_fail
mov expansionStage,5
mov playerX,FP_1*294/10
mov playerY,21*FP_1
mov playerAngle,0
mov keys3D[57h],1
xor esi,esi
expansion_upper_walk:
call ExpansionWalkFrame
cmp engineMode,MODE_WALK
jne @F
cmp hallLevel3D,2
je expansion_at_upper
@@:
inc esi
cmp esi,1100
jb expansion_upper_walk
jmp expansion_fail
expansion_at_upper:
mov keys3D[57h],0
cmp worldMap3D,OFFSET upperLoungeMap3D
jne expansion_fail
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionUpper
mov expansionStage,6
mov playerX,7*FP_1
mov playerY,FP_1*187/10
mov playerAngle,384
call UpdateCamera3D
call CheckInteractions
cmp interactTargetId,INTERACT_BUCKSHOT
jne expansion_fail
mov playerX,12*FP_1
mov playerY,FP_1*197/10
call CheckInteractions
cmp interactTargetId,INTERACT_RUSSIAN_ROULETTE
jne expansion_fail
mov playerX,9*FP_1
mov playerY,FP_1*221/10
mov playerX,FP_1*91/10
mov playerAngle,128
call UpdateCamera3D
call CheckInteractions
cmp interactTargetId,INTERACT_UPPER_LEFT
jne expansion_fail
mov playerX,13*FP_1
mov playerY,FP_1*163/10
mov playerAngle,384
call UpdateCamera3D
call CheckInteractions
cmp interactTargetId,INTERACT_BAR
jne expansion_fail
call TriggerHallInteraction3D
cmp engineMode,MODE_BAR
jne expansion_fail
call RenderBar3D
cmp playerX,13*FP_1
jne expansion_fail
cmp hallLevel3D,2
jne expansion_fail
invoke ExpansionSnapshot,OFFSET expansionUpperBar
mov expansionStage,7
mov engineMode,MODE_WALK
mov playerX,4*FP_1
mov playerY,21*FP_1
mov playerAngle,256
mov keys3D[57h],1
xor esi,esi
expansion_descend_upper:
call ExpansionWalkFrame
cmp engineMode,MODE_WALK
jne @F
cmp hallLevel3D,0
je expansion_upper_returned
@@:
inc esi
cmp esi,1100
jb expansion_descend_upper
jmp expansion_fail
expansion_upper_returned:
mov keys3D[57h],0
; No key held: neither position nor floor changes even after a long wait.
mov engineMode,MODE_STAIRS
mov stairRoute3D,2
mov worldMap3D,OFFSET upperStairMap3D
mov floorTexture3D,85
mov playerX,7*FP_1
mov playerY,21*FP_1
mov playerAngle,0
mov deltaTime3D,5000
call HandleStairs3D
cmp playerX,7*FP_1
jne expansion_fail
cmp engineMode,MODE_STAIRS
jne expansion_fail
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionStairs
mov playerX,11*FP_1
call UpdateStairHeight3D
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionStairsMid
mov expansionStage,8
mov deltaTime3D,16
mov hallLevel3D,0
mov worldMap3D,OFFSET casinoMap
mov floorTexture3D,100
mov playerX,16*FP_1
mov playerY,FP_1*67/10
mov playerAngle,384
mov cabaretTime3D,30000
call UpdateCabaret3D
call BeginCabaret3D
mov animationClock3D,0
call RenderCabaret3D
invoke ExpansionSnapshot,OFFSET expansionJazz
mov animationClock3D,200
call RenderCabaret3D
cmp cabaretPiano3D.frame,1
jne expansion_fail
cmp cabaretGuitar3D.frame,1
jne expansion_fail
invoke ExpansionSnapshot,OFFSET expansionJazz1
mov animationClock3D,400
call RenderCabaret3D
invoke ExpansionSnapshot,OFFSET expansionJazz2
mov animationClock3D,600
call RenderCabaret3D
cmp cabaretPiano3D.frame,3
jne expansion_fail
cmp cabaretGuitar3D.frame,3
jne expansion_fail
invoke ExpansionSnapshot,OFFSET expansionJazz3
mov cabaretTime3D,0
call UpdateCabaret3D
call RenderCabaret3D
invoke ExpansionSnapshot,OFFSET expansionChorus
mov pressedKeys3D[45h],1
call HandleCabaret3D
cmp engineMode,MODE_WALK
jne expansion_fail
mov bankroll,100
call BeginCabaret3D
mov mouseClick3D,1
mov mouseX3D,40
mov mouseY3D,220
call HandleCabaret3D
cmp bankroll,0
jne expansion_fail
mov mouseClick3D,1
call HandleCabaret3D
cmp bankroll,0
jne expansion_fail
mov mouseClick3D,1
mov mouseX3D,280
call HandleCabaret3D
cmp engineMode,MODE_WALK
jne expansion_fail
mov expansionStage,9
; Each visitor maps to their own frame block, not the first man's idle pose.
mov playerX,16*FP_1
mov playerY,20*FP_1
mov playerAngle,384
xor esi,esi
expansion_cast_positions:
imul ebx,esi,SIZEOF NpcMindEntity
imul eax,esi,FP_1
add eax,FP_1*27/2
mov casinoNpcs3D[ebx].posX,eax
mov casinoNpcs3D[ebx].posY,16*FP_1
imul ebx,esi,SIZEOF NpcLife3D
mov npcLife3D[ebx].identity,esi
mov npcLife3D[ebx].state,NPC_STAND
inc esi
cmp esi,6
jb expansion_cast_positions
call UpdateInteriorEye3D
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionCast
mov hallLevel3D,2
mov worldMap3D,OFFSET upperLoungeMap3D
mov floorTexture3D,124
mov playerX,7*FP_1
mov playerY,FP_1*194/10
mov playerAngle,384
call UpdateInteriorEye3D
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionBuckshotTable
mov playerX,12*FP_1
mov playerY,FP_1*204/10
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionRussianTable
mov playerX,FP_1*125/10
mov playerY,FP_1*168/10
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionBarWorld
mov playerX,FP_1*56/10
mov playerY,FP_1*205/10
mov playerAngle,128
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionSeating
mov expansionStage,20
mov hallLevel3D,0
mov worldMap3D,OFFSET casinoMap
mov floorTexture3D,100
mov playerX,FP_1*285/10
mov playerY,21*FP_1
mov playerAngle,0
invoke ExpansionPortalSnapshot,OFFSET expansionUpEntry
invoke DrawCityVertical3D,0,29*FP_1,FP_1*208/10,FP_1*212/10,0,FP_1*22/10,122
mov eax,screenBuffer[(240*SCREEN_W+320)*4]
mov expansionOcclusionPixel,eax
call RenderInteriorViews3D
mov eax,screenBuffer[(240*SCREEN_W+320)*4]
cmp eax,expansionOcclusionPixel
jne expansion_fail
mov expansionStage,21
mov engineMode,MODE_STAIRS
mov stairRoute3D,2
mov worldMap3D,OFFSET upperStairMap3D
mov floorTexture3D,85
mov playerX,FP_1*48/10
mov playerAngle,256
invoke ExpansionPortalSnapshot,OFFSET expansionUpReturn
mov expansionStage,22
mov playerX,15*FP_1
mov playerAngle,0
invoke ExpansionPortalSnapshot,OFFSET expansionUpLanding
mov expansionStage,23
mov engineMode,MODE_WALK
mov hallLevel3D,2
mov worldMap3D,OFFSET upperLoungeMap3D
mov floorTexture3D,124
mov playerX,FP_1*45/10
mov playerAngle,256
invoke ExpansionPortalSnapshot,OFFSET expansionUpExit
mov expansionStage,24
mov hallLevel3D,0
mov worldMap3D,OFFSET casinoMap
mov floorTexture3D,100
mov playerX,FP_1*267/10
mov playerY,FP_1*105/10
mov playerAngle,0
mov basementDoorOpen3D,0
call UpdateInteriorEye3D
call ExpansionFrame
cmp portalPixelsWritten3D,0
jne expansion_fail
invoke ExpansionSnapshot,OFFSET expansionDownClosed
mov basementDoorOpen3D,FP_1
invoke ExpansionPortalSnapshot,OFFSET expansionDoor
mov expansionStage,25
mov engineMode,MODE_STAIRS
mov stairRoute3D,1
mov worldMap3D,OFFSET basementStairMap3D
mov floorTexture3D,94
mov playerX,FP_1*45/10
mov playerY,21*FP_1
mov playerAngle,256
invoke ExpansionPortalSnapshot,OFFSET expansionDownReturn
mov expansionStage,26
mov playerX,FP_1*165/10
mov playerY,FP_1*155/10
mov playerAngle,384
invoke ExpansionPortalSnapshot,OFFSET expansionDownLanding
mov expansionStage,27
mov engineMode,MODE_WALK
mov hallLevel3D,1
mov worldMap3D,OFFSET bunkerMap3D
mov playerY,FP_1*265/10
mov playerAngle,128
invoke ExpansionPortalSnapshot,OFFSET expansionBunkerReturn
mov expansionStage,28
mov hallLevel3D,2
mov worldMap3D,OFFSET upperLoungeMap3D
mov floorTexture3D,124
mov playerX,FP_1*105/10
mov playerY,FP_1*193/10
mov upperLeverMask3D,0
mov upperPortalReady3D,0
mov upperLeverTime3D,0
mov upperLeverTime3D[4],0
call UpdateInteriorEye3D
call ExpansionFrame
invoke ExpansionSnapshot,OFFSET expansionPortalClosed
mov interactTargetId,INTERACT_UPPER_LEFT
call TriggerHallInteraction3D
mov esi,40
expansion_first_lever:
add animationClock3D,16
call UpdateUpperEffects3D
dec esi
jnz expansion_first_lever
cmp upperLeverTime3D,600
jne expansion_fail
cmp upperLeverTime3D[4],0
jne expansion_fail
cmp upperPortalReady3D,0
jne expansion_fail
mov playerY,FP_1*244/10
call TryWalkUpperPortal3D
cmp engineMode,MODE_WALK
jne expansion_fail
mov playerY,FP_1*193/10
mov interactTargetId,INTERACT_UPPER_RIGHT
call TriggerHallInteraction3D
mov esi,20
expansion_second_lever_half:
add animationClock3D,16
call UpdateUpperEffects3D
dec esi
jnz expansion_second_lever_half
cmp upperPortalReady3D,0
jne expansion_fail
call ExpansionFrame
cmp upperLever3D.frame,2
jne expansion_fail
invoke ExpansionSnapshot,OFFSET expansionLeverMid
mov esi,20
expansion_second_lever_end:
add animationClock3D,16
call UpdateUpperEffects3D
dec esi
jnz expansion_second_lever_end
cmp upperPortalReady3D,1
jne expansion_fail
xor esi,esi
expansion_portal_motion:
imul eax,esi,80
mov animationClock3D,eax
call ExpansionFrame
mov eax,esi
inc eax
cmp upperPortal3D.frame,eax
jne expansion_fail
invoke ExpansionSnapshot,expansionPortalPaths[esi*4]
inc esi
cmp esi,12
jb expansion_portal_motion
mov playerY,FP_1*244/10
call TryWalkUpperPortal3D
cmp engineMode,MODE_HELL_TOWER
jne expansion_fail
call TowerExitToHall
call TryWalkUpperPortal3D
cmp engineMode,MODE_WALK
jne expansion_fail
mov expansionStage,30
mov hallLevel3D,0
mov worldMap3D,OFFSET casinoMap
mov floorTexture3D,100
mov playerX,FP_1*285/10
mov playerY,21*FP_1
mov playerAngle,0
call UpdateInteriorEye3D
call ExpansionFrame
cld
lea esi,screenBuffer
lea edi,expansionSinglePixels
mov ecx,SCREEN_SIZE
rep movsd
invoke CreateEventA,0,0,0,0
mov hRaycastStartEvent,eax
invoke CreateEventA,0,0,0,0
mov hRaycastDoneEvent,eax
mov bRaycastQuit,0
invoke CreateThread,0,65536,OFFSET RaycastWorkerProc,0,0,OFFSET raycastThreadId
mov hRaycastThread,eax
test eax,eax
jz expansion_fail
call ExpansionFrame
lea esi,screenBuffer
lea edi,expansionSinglePixels
mov ecx,SCREEN_SIZE
repe cmpsd
jne expansion_fail
mov bRaycastQuit,1
invoke SetEvent,hRaycastStartEvent
invoke WaitForSingleObject,hRaycastThread,2000
test eax,eax
jnz expansion_fail
invoke CloseHandle,hRaycastThread
invoke CloseHandle,hRaycastStartEvent
invoke CloseHandle,hRaycastDoneEvent
mov hRaycastThread,0
mov hRaycastStartEvent,0
mov hRaycastDoneEvent,0
invoke ExitProcess,0
expansion_fail:
invoke ExitProcess,expansionStage
ret
ExpansionTestStart ENDP