ROOF_NAV_W equ 70 ROOF_NAV_H equ 78 .data roofTestHall db "build\hall-expansion\roof-lift-hall.bmp",0 roofTestOpening db "build\hall-expansion\roof-lift-opening.bmp",0 roofTestCabin db "build\hall-expansion\roof-lift-cabin.bmp",0 roofTestEntry db "build\hall-expansion\roof-arrival.bmp",0 roofTestSouth db "build\hall-expansion\roof-terrace.bmp",0 roofTestEast db "build\hall-expansion\roof-city-east.bmp",0 roofTestWest db "build\hall-expansion\roof-city-west.bmp",0 roofTestSeated db "build\hall-expansion\roof-seated.bmp",0 roofTestBar db "build\hall-expansion\roof-bar.bmp",0 roofTestMix db "build\hall-expansion\roof-bar-mixing.bmp",0 roofTestReturn db "build\hall-expansion\roof-return.bmp",0 roofTestChairSide db "build\hall-expansion\roof-chair-side.bmp",0 roofTestChairBack db "build\hall-expansion\roof-chair-back.bmp",0 roofTestPlanter db "build\hall-expansion\roof-planter.bmp",0 roofTestLean db "build\hall-expansion\roof-lean.bmp",0 roofTestNight db "build\hall-expansion\roof-night.bmp",0 roofTestHDEast db "build\hall-expansion\roof-hd-east.bmp",0 roofTestHDSouth db "build\hall-expansion\roof-hd-south.bmp",0 roofTestHDNight db "build\hall-expansion\roof-hd-night.bmp",0 roofTestHDComposite db "build\hall-expansion\roof-hd-terrace.bmp",0 roofTestHDMotion db "build\hall-expansion\roof-hd-traffic.bmp",0 roofTestHDLeft db "build\hall-expansion\roof-hd-look-left.bmp",0 roofTestHDRight db "build\hall-expansion\roof-hd-look-right.bmp",0 roofTestHDEco db "build\hall-expansion\roof-hd-eco.bmp",0 roofTestHDAuto db "build\hall-expansion\roof-hd-auto.bmp",0 roofTestSoftware db "build\hall-expansion\roof-software-ground.bmp",0 roofTestMissingArt db "build\hall-expansion\roof-missing-art-ground.bmp",0 roofTestHDTiming db "build\hall-expansion\roof-hd-timing.bin",0 roofTestDriver db "build\hall-expansion\roof-driver.txt",0 roofTestNewline db 13,10 roofTestHDMillis dd 0,24,0,0,0 roofTestHDBmp db 42h,4Dh dd 54+ROOF_HD_W*ROOF_HD_H*4 dw 0,0 dd 54,40,ROOF_HD_W,-ROOF_HD_H dw 1,32 dd 0,ROOF_HD_W*ROOF_HD_H*4,0,0,0,0 roofTestHDBMI dd 40,ROOF_HD_W,-ROOF_HD_H dw 1,32 dd 0,ROOF_HD_W*ROOF_HD_H*4,0,0,0,0 roofTestHDDC dd 0 roofTestHDBitmap dd 0 roofTestHDPixels dd 0 roofTestHDOld dd 0 roofTestLeanMove db "build\hall-expansion\roof-lean-motion.bin",0 roofTestGuestX dd 0 roofTestFloorColor dd 0 roofTestBank dd 0 roofTestX dd 0 roofTestY dd 0 roofTestCrash db "build\hall-expansion\roof-crash.bin",0 roofTestNavPath db "build\hall-expansion\roof-navigation.bin",0 roofTestNavHeader dd ROOF_NAV_W,ROOF_NAV_H,FP_1*45/4,FP_1*5/4,FP_1/4,ROOF_SEAT_COUNT .data? roofTestWalkPixels db ROOF_NAV_W*ROOF_NAV_H dup(?) .code RoofTestHDSnapshot PROC uses ebx path:DWORD local count:DWORD call UpdateCamera3D call RenderRoof3D invoke PresentRoofHD3D,roofTestHDDC,0,0,ROOF_HD_W,ROOF_HD_H test eax,eax jz roof_test_hd_capture_failed invoke GdiFlush invoke CreateFileA,path,40000000h,0,0,2,80h,0 mov ebx,eax invoke WriteFile,ebx,OFFSET roofTestHDBmp,54,ADDR count,0 invoke WriteFile,ebx,roofTestHDPixels,ROOF_HD_W*ROOF_HD_H*4,ADDR count,0 invoke CloseHandle,ebx ret roof_test_hd_capture_failed: invoke ExitProcess,95 ret RoofTestHDSnapshot ENDP RoofTestHD PROC uses ebx esi local started:DWORD,written:DWORD,driverPtr:DWORD,driverLen:DWORD mov expansionStage,94 mov roofQualityMode3D,2 call InitRoofHD3D test eax,eax jnz roof_test_hd_ready mov eax,roofHDStage3D add eax,100 invoke ExitProcess,eax roof_test_hd_ready: invoke CreateFileA,OFFSET roofTestDriver,40000000h,0,0,2,80h,0 mov ebx,eax mov esi,1F00h roof_test_driver_string: invoke glGetString,esi mov driverPtr,eax xor ecx,ecx roof_test_driver_length: cmp BYTE PTR [eax+ecx],0 je roof_test_driver_write inc ecx jmp roof_test_driver_length roof_test_driver_write: mov driverLen,ecx invoke WriteFile,ebx,driverPtr,driverLen,ADDR written,0 invoke WriteFile,ebx,OFFSET roofTestNewline,2,ADDR written,0 inc esi cmp esi,1F02h jbe roof_test_driver_string invoke CloseHandle,ebx invoke CreateCompatibleDC,0 mov roofTestHDDC,eax invoke CreateDIBSection,eax,OFFSET roofTestHDBMI,0,OFFSET roofTestHDPixels,0,0 mov roofTestHDBitmap,eax invoke SelectObject,roofTestHDDC,eax mov roofTestHDOld,eax mov hallLevel3D,HALL_ROOF mov engineMode,MODE_WALK mov worldMap3D,OFFSET roofMap3D mov floorTexture3D,ROOF_DECK mov playerX,FP_1*275/10 mov playerY,10*FP_1 mov playerAngle,0 mov roofLean3D,2 mov roofLeanAngle3D,0 mov roofLeanTime3D,1100 mov roofNight3D,0 mov keys3D[41h],1 mov deltaTime3D,16 add animationClock3D,16 call UpdateRoof3D cmp roofLean3D,2 jne roof_test_hd_failed cmp playerAngle,0 je roof_test_hd_failed mov keys3D[41h],0 mov playerAngle,0 invoke RoofTestHDSnapshot,OFFSET roofTestHDEast add animationClock3D,1600 invoke RoofTestHDSnapshot,OFFSET roofTestHDMotion mov playerAngle,464 invoke RoofTestHDSnapshot,OFFSET roofTestHDLeft cmp roofLean3D,2 jne roof_test_hd_failed cmp playerAngle,464 jne roof_test_hd_failed cmp roofHandsContactX3D,320 jle roof_test_hd_failed mov playerAngle,48 invoke RoofTestHDSnapshot,OFFSET roofTestHDRight cmp playerAngle,48 jne roof_test_hd_failed cmp roofHandsContactX3D,320 jge roof_test_hd_failed mov playerAngle,180 call UpdateRoofLook3D cmp playerAngle,104 jne roof_test_hd_failed call RenderRoof3D invoke PresentRoofHD3D,roofTestHDDC,0,0,ROOF_HD_W,ROOF_HD_H test eax,eax jz roof_test_hd_failed mov playerAngle,408 call RenderRoof3D invoke PresentRoofHD3D,roofTestHDDC,0,0,ROOF_HD_W,ROOF_HD_H test eax,eax jz roof_test_hd_failed mov roofLean3D,0 mov playerX,20*FP_1 mov playerY,20*FP_1 mov playerAngle,128 invoke RoofTestHDSnapshot,OFFSET roofTestHDSouth mov roofNight3D,1 invoke RoofTestHDSnapshot,OFFSET roofTestHDNight mov roofNight3D,0 mov playerX,20*FP_1 mov playerY,7*FP_1 invoke RoofTestHDSnapshot,OFFSET roofTestHDComposite invoke GetTickCount mov started,eax mov esi,24 roof_test_hd_frame_time: add animationClock3D,16 call RenderRoof3D invoke PresentRoofHD3D,roofTestHDDC,0,0,ROOF_HD_W,ROOF_HD_H test eax,eax jz roof_test_hd_failed dec esi jnz roof_test_hd_frame_time invoke GdiFlush invoke GetTickCount sub eax,started mov roofTestHDMillis,eax invoke GetTickCount mov started,eax mov esi,24 roof_test_cpu_only_time: call RenderRoof3D dec esi jnz roof_test_cpu_only_time invoke GetTickCount sub eax,started mov roofTestHDMillis[8],eax invoke GetTickCount mov started,eax mov esi,24 roof_test_gpu_only_time: add animationClock3D,33 call RenderRoofHD3D dec esi jnz roof_test_gpu_only_time invoke GetTickCount sub eax,started mov roofTestHDMillis[12],eax invoke GetTickCount mov started,eax mov esi,24 roof_test_present_only_time: invoke PresentRoofHD3D,roofTestHDDC,0,0,ROOF_HD_W,ROOF_HD_H dec esi jnz roof_test_present_only_time invoke GdiFlush invoke GetTickCount sub eax,started mov roofTestHDMillis[16],eax invoke CreateFileA,OFFSET roofTestHDTiming,40000000h,0,0,2,80h,0 mov ebx,eax invoke WriteFile,ebx,OFFSET roofTestHDMillis,20,ADDR written,0 invoke CloseHandle,ebx ; Quality profiles retain the full scene and a correctly aligned foreground. mov playerX,FP_1*275/10 mov playerY,10*FP_1 mov playerAngle,0 mov roofLean3D,2 mov roofLeanAngle3D,0 mov roofQualityMode3D,1 invoke RoofTestHDSnapshot,OFFSET roofTestHDEco cmp roofRenderW3D,640 jne roof_test_hd_failed cmp roofRenderH3D,480 jne roof_test_hd_failed mov roofQualityMode3D,0 mov roofAutoWidth3D,960 invoke RoofTestHDSnapshot,OFFSET roofTestHDAuto cmp roofRenderW3D,960 jne roof_test_hd_failed mov deltaTime3D,100 mov roofQualitySlow3D,0 mov esi,11 roof_test_auto_slow: add animationClock3D,100 call UpdateRoofQuality3D dec esi jnz roof_test_auto_slow cmp roofRenderW3D,640 jne roof_test_hd_failed call ClearKeys3D invoke WindowEvents3D,0,100h,77h,0 add animationClock3D,16 call UpdateRoofQuality3D cmp roofQualityMode3D,1 jne roof_test_hd_failed call ClearKeys3D invoke WindowEvents3D,0,100h,77h,0 add animationClock3D,16 call UpdateRoofQuality3D cmp roofQualityMode3D,2 jne roof_test_hd_failed cmp roofRenderW3D,1280 jne roof_test_hd_failed call ClearKeys3D mov roofLean3D,0 invoke SelectObject,roofTestHDDC,roofTestHDOld invoke DeleteObject,roofTestHDBitmap invoke DeleteDC,roofTestHDDC call FreeRoofHD3D cmp roofHDWindow3D,0 jne roof_test_hd_failed cmp roofHDBuffer3D,0 jne roof_test_hd_failed cmp roofHDRC3D,0 jne roof_test_hd_failed cmp roofHDMeshScene3D[12],0 jne roof_test_hd_failed cmp roofHDFinalDC3D,0 jne roof_test_hd_failed cmp roofHDFinalBmp3D,0 jne roof_test_hd_failed ; Capability failure must return to software, without repeatedly opening contexts. mov roofHDReady3D,-1 invoke PresentRoofHD3D,0,0,0,1280,960 test eax,eax jnz roof_test_hd_failed cmp roofHDReady3D,-1 jne roof_test_hd_failed ; Software roads and water remain visible even if the city pack is missing. mov deltaTime3D,16 mov roofQualityMode3D,0 mov roofAutoWidth3D,960 call UpdateCamera3D call RenderRoof3D cmp roofGroundRoadPixels3D,0 je roof_test_hd_failed cmp roofGroundWaterPixels3D,0 je roof_test_hd_failed invoke ExpansionSnapshot,OFFSET roofTestSoftware mov eax,roofCityArt3D.pixels push eax mov roofCityArt3D.pixels,0 call RenderRoof3D cmp roofGroundRoadPixels3D,0 je roof_test_hd_failed cmp roofGroundWaterPixels3D,0 je roof_test_hd_failed invoke ExpansionSnapshot,OFFSET roofTestMissingArt pop eax mov roofCityArt3D.pixels,eax mov roofHDReady3D,0 ret roof_test_hd_failed: invoke ExitProcess,94 ret RoofTestHD ENDP RoofTestNavigation PROC uses ebx esi edi local px:DWORD,py:DWORD,written:DWORD lea edi,roofTestWalkPixels xor esi,esi roof_test_nav_row: mov eax,esi imul eax,FP_1/4 add eax,FP_1*5/4 mov py,eax xor ebx,ebx roof_test_nav_column: mov eax,ebx imul eax,FP_1/4 add eax,FP_1*45/4 mov px,eax invoke CanWalk3D,px,py mov [edi],al inc edi inc ebx cmp ebx,ROOF_NAV_W jb roof_test_nav_column inc esi cmp esi,ROOF_NAV_H jb roof_test_nav_row invoke CreateFileA,OFFSET roofTestNavPath,40000000h,0,0,2,80h,0 mov ebx,eax invoke WriteFile,ebx,OFFSET roofTestNavHeader,24,ADDR written,0 invoke WriteFile,ebx,OFFSET roofSeatX3D,ROOF_SEAT_COUNT*4,ADDR written,0 invoke WriteFile,ebx,OFFSET roofSeatY3D,ROOF_SEAT_COUNT*4,ADDR written,0 invoke WriteFile,ebx,OFFSET roofSeatKind3D,ROOF_SEAT_COUNT*4,ADDR written,0 invoke WriteFile,ebx,OFFSET roofTestWalkPixels,ROOF_NAV_W*ROOF_NAV_H,ADDR written,0 invoke CloseHandle,ebx ret RoofTestNavigation ENDP RoofTestCrashFilter PROC uses ebx esi pointers:DWORD local written:DWORD mov esi,pointers mov esi,[esi+4] invoke CreateFileA,OFFSET roofTestCrash,40000000h,0,0,2,80h,0 mov ebx,eax invoke WriteFile,ebx,esi,204,ADDR written,0 invoke CloseHandle,ebx invoke ExitProcess,expansionStage mov eax,1 ret RoofTestCrashFilter ENDP RoofTestTicks PROC uses esi count:DWORD mov esi,count roof_test_tick: mov deltaTime3D,16 add animationClock3D,16 call UpdateInteriorTravel3D call UpdateInteriorEye3D dec esi jnz roof_test_tick ret RoofTestTicks ENDP RoofNativeTests PROC uses ebx esi edi invoke SetUnhandledExceptionFilter,OFFSET RoofTestCrashFilter mov expansionStage,90 mov eax,bankroll mov roofTestBank,eax call InitRoof3D call LoadRoofAssets3D cmp roofSkyArt3D.imageWidth,512 jne roof_test_fail cmp roofSkyArt3D.frames,4 jne roof_test_fail cmp roofDetailArt3D.frames,15 jne roof_test_fail cmp roofHandsArt3D.frames,32 jne roof_test_fail cmp roofCityArt3D.frames,22 jne roof_test_fail cmp roofNightArt3D.frames,4 jne roof_test_fail xor esi,esi roof_test_surface_theme: mov roofNight3D,esi mov ebx,ROOF_DECK roof_test_surface: invoke ResolveRoofSurface3D,ebx cmp eax,65535 jbe roof_test_fail mov edx,256 cmp ebx,ROOF_FACADE jb @F mov edx,512 @@: cmp ebx,ROOF_INDICATOR jne @F mov edx,64 @@: cmp ebx,ROOF_LIGHT jne @F mov edx,1 @@: cmp ecx,edx jne roof_test_fail inc ebx cmp ebx,ROOF_LAST_MATERIAL jbe roof_test_surface inc esi cmp esi,2 jb roof_test_surface_theme mov roofNight3D,0 invoke CityRayPlane3D,-512*FP_1,24*FP_1,405 cmp eax,7FFFFFFFh jne roof_test_fail mov engineMode,MODE_WALK mov hallLevel3D,0 mov worldMap3D,OFFSET casinoMap mov floorTexture3D,100 mov playerX,LIFT_CENTRE_X mov playerY,FP_1*63/10 mov playerAngle,384 call UpdateCamera3D call UpdateInteriorEye3D call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestHall mov playerY,FP_1*48/10 call UpdateCamera3D invoke CanWalk3D,LIFT_CENTRE_X,FP_1*34/10 test eax,eax jnz roof_test_fail call CheckInteractions cmp interactTargetId,INTERACT_LIFT_CALL jne roof_test_fail call TriggerHallInteraction3D cmp liftPhase3D,1 jne roof_test_fail invoke RoofTestTicks,32 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestOpening invoke RoofTestTicks,36 cmp liftDoor3D,1000 jne roof_test_fail invoke CanWalk3D,LIFT_CENTRE_X,FP_1*34/10 test eax,eax jz roof_test_fail ; Walk through the opened doorway using the actual normal movement handler. mov keys3D[57h],1 mov esi,120 roof_test_walk_in: call ExpansionWalkFrame cmp playerY,FP_1*26/10 jb roof_test_inside dec esi jnz roof_test_walk_in jmp roof_test_fail roof_test_inside: call ClearKeys3D mov eax,playerX mov roofTestX,eax mov eax,playerY mov roofTestY,eax cmp hallLevel3D,0 jne roof_test_fail invoke WindowEvents3D,0,100h,32h,0 invoke RoofTestTicks,1 cmp roofNight3D,1 jne roof_test_fail call ClearKeys3D invoke WindowEvents3D,0,100h,31h,0 invoke RoofTestTicks,1 cmp roofNight3D,0 jne roof_test_fail call ClearKeys3D call CheckInteractions cmp interactTargetId,INTERACT_LIFT_TRAVEL jne roof_test_fail call TriggerHallInteraction3D cmp liftPhase3D,3 jne roof_test_fail invoke CanWalk3D,LIFT_CENTRE_X,2*FP_1 test eax,eax jnz roof_test_fail invoke RoofTestTicks,68 cmp liftPhase3D,4 jne roof_test_fail cmp hallLevel3D,0 jne roof_test_fail call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestCabin invoke RoofTestTicks,270 cmp hallLevel3D,HALL_ROOF jne roof_test_fail cmp worldMap3D,OFFSET roofMap3D jne roof_test_fail cmp liftPhase3D,2 jne roof_test_fail mov eax,roofTestX cmp playerX,eax jne roof_test_fail mov eax,roofTestY cmp playerY,eax jne roof_test_fail mov playerAngle,128 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestEntry mov keys3D[57h],1 mov esi,120 roof_test_walk_out: call ExpansionWalkFrame cmp playerY,FP_1*46/10 ja roof_test_outside dec esi jnz roof_test_walk_out jmp roof_test_fail roof_test_outside: call ClearKeys3D call RoofTestNavigation mov expansionStage,91 invoke CanWalk3D,29*FP_1,10*FP_1 test eax,eax jnz roof_test_fail invoke CanWalk3D,15*FP_1,FP_1*45/10 test eax,eax jnz roof_test_fail invoke CanWalk3D,FP_1*145/10,10*FP_1 test eax,eax jnz roof_test_fail invoke CanWalk3D,FP_1*145/10,FP_1*77/10 test eax,eax jnz roof_test_fail invoke CanWalk3D,12*FP_1,FP_1*68/10 test eax,eax jnz roof_test_fail mov playerX,20*FP_1 mov playerY,FP_1*66/10 mov playerAngle,128 call UpdateCamera3D call UpdateRoofEye3D call RenderCeilingAndFloor mov eax,screenBuffer[(460*640+320)*4] mov roofTestFloorColor,eax call ExpansionFrame mov eax,roofTestFloorColor cmp screenBuffer[(460*640+320)*4],eax jne roof_test_fail cmp cityDepthBuffer3D[(460*640+320)*4],4*FP_1 ja roof_test_fail cmp playerX,20*FP_1 jne roof_test_fail cmp playerY,FP_1*66/10 jne roof_test_fail invoke ExpansionSnapshot,OFFSET roofTestSouth mov playerAngle,0 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestEast mov playerAngle,256 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestWest mov playerX,FP_1*145/10 mov playerY,FP_1*84/10 mov playerAngle,128 call UpdateCamera3D call CheckInteractions cmp interactTargetId,INTERACT_ROOF_SEAT jne roof_test_fail call TriggerHallInteraction3D call UpdateInteriorEye3D cmp roofSeat3D,1 jne roof_test_fail cmp viewEye3D,ROOF_SEATED_EYE jne roof_test_fail call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestSeated mov keys3D[57h],1 invoke RoofTestTicks,1 cmp roofSeat3D,0 jne roof_test_fail cmp playerY,FP_1*84/10 jne roof_test_fail call ClearKeys3D xor ebx,ebx roof_test_all_seats: mov playerX,20*FP_1 mov playerY,7*FP_1 mov playerAngle,128 mov roofTargetSeat3D,ebx mov interactTargetId,INTERACT_ROOF_SEAT call TryRoofInteraction3D lea eax,[ebx+1] cmp roofSeat3D,eax jne roof_test_fail call UpdateRoofEye3D mov eax,ROOF_SEATED_EYE cmp roofSeatKind3D[ebx*4],2 jb @F mov eax,ROOF_STANDING_EYE @@: cmp viewEye3D,eax jne roof_test_fail mov eax,384 cmp roofSeatKind3D[ebx*4],3 jne @F mov eax,256 @@: cmp playerAngle,eax jne roof_test_fail mov interactTargetId,INTERACT_ROOF_SEAT call TryRoofInteraction3D cmp roofSeat3D,0 jne roof_test_fail cmp playerX,20*FP_1 jne roof_test_fail cmp playerY,7*FP_1 jne roof_test_fail cmp playerAngle,128 jne roof_test_fail call UpdateRoofEye3D inc ebx cmp ebx,ROOF_SEAT_COUNT jb roof_test_all_seats mov expansionStage,92 mov playerX,20*FP_1 mov playerY,7*FP_1 mov engineMode,MODE_BAR mov barPhase3D,0 mov esi,30 roof_test_bar_repeat: call RenderBar3D cmp playerX,20*FP_1 jne roof_test_fail cmp playerY,7*FP_1 jne roof_test_fail cmp viewEye3D,ROOF_STANDING_EYE jne roof_test_fail dec esi jnz roof_test_bar_repeat invoke ExpansionSnapshot,OFFSET roofTestBar mov barPhase3D,1 mov barSelection3D,1 mov barTime3D,1500 call RenderBar3D invoke ExpansionSnapshot,OFFSET roofTestMix mov engineMode,MODE_WALK mov barPhase3D,0 ; Scale and full furniture volumes must survive side and back inspection. mov expansionStage,93 mov playerX,FP_1*191/10 mov playerY,10*FP_1 mov playerAngle,256 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestChairSide mov playerX,FP_1*177/10 mov playerY,FP_1*116/10 mov playerAngle,384 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestChairBack mov playerX,FP_1*167/10 mov playerY,FP_1*197/10 mov playerAngle,256 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestPlanter ; The native gait advances position while every step respects roof collision. mov eax,roofGuestX3D[0] mov roofTestGuestX,eax mov roofGuestWait3D[0],0 mov roofGuestDir3D[0],0 invoke RoofTestTicks,20 mov eax,roofGuestX3D[0] cmp eax,roofTestGuestX je roof_test_fail cmp roofGuestMoving3D[0],1 jne roof_test_fail mov playerX,FP_1*275/10 mov playerY,10*FP_1 mov playerAngle,0 call UpdateCamera3D call CheckRoofInteractions3D cmp interactTargetId,INTERACT_ROOF_RAIL jne roof_test_fail call TryRoofInteraction3D cmp roofLean3D,1 jne roof_test_fail invoke RoofTestTicks,75 cmp roofLean3D,2 jne roof_test_fail cmp roofLeanTime3D,1100 jne roof_test_fail call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestLean invoke CanWalk3D,27*FP_1,10*FP_1 test eax,eax jnz roof_test_fail mov roofNight3D,1 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestNight mov roofNight3D,0 mov interactTargetId,INTERACT_ROOF_RAIL call TryRoofInteraction3D invoke RoofTestTicks,40 cmp roofLean3D,0 jne roof_test_fail cmp playerX,FP_1*275/10 jne roof_test_fail cmp playerY,10*FP_1 jne roof_test_fail cmp viewEye3D,ROOF_STANDING_EYE jne roof_test_fail mov expansionStage,92 invoke RoofTestTicks,250 cmp liftDoor3D,0 jne roof_test_fail mov playerX,LIFT_CENTRE_X mov playerY,FP_1*48/10 mov playerAngle,384 call UpdateCamera3D call CheckInteractions call TriggerHallInteraction3D invoke RoofTestTicks,70 mov playerY,FP_1*24/10 call CheckInteractions cmp interactTargetId,INTERACT_LIFT_TRAVEL jne roof_test_fail call TriggerHallInteraction3D invoke RoofTestTicks,340 cmp hallLevel3D,0 jne roof_test_fail cmp worldMap3D,OFFSET casinoMap jne roof_test_fail mov playerY,FP_1*48/10 call ExpansionFrame invoke ExpansionSnapshot,OFFSET roofTestReturn mov eax,bankroll cmp eax,roofTestBank jne roof_test_fail call FreeRoofAssets3D cmp roofSkyArt3D.pixels,0 jne roof_test_fail cmp roofMaterialArt3D.pixels,0 jne roof_test_fail cmp roofDetailArt3D.pixels,0 jne roof_test_fail call LoadRoofAssets3D call RoofTestHD mov hallLevel3D,0 mov worldMap3D,OFFSET casinoMap ret roof_test_fail: invoke ExitProcess,expansionStage ret RoofNativeTests ENDP