.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