; Native Backrooms: connected DFS maze, rooms/loops, BFS farthest exit. LoadBackroomsAssets3D PROC uses esi edi invoke LoadAnimPack3D,OFFSET brMaterials3D,OFFSET brMaterialPath3D test eax,eax jz br_assets_done cmp brMaterials3D.imageWidth,128 jne br_assets_invalid cmp brMaterials3D.height,128 jne br_assets_invalid cmp brMaterials3D.frames,5 jne br_assets_invalid mov esi,brMaterials3D.pixels mov edi,OFFSET texturesBuffer+BR_WALL*65536 mov ecx,5*128*128 rep movsd mov eax,1 ret br_assets_invalid: invoke FreeAnimPack3D,OFFSET brMaterials3D xor eax,eax br_assets_done: ret LoadBackroomsAssets3D ENDP GenerateBackrooms3D PROC uses ebx esi edi local top:DWORD,count:DWORD,current:DWORD,next:DWORD,tail:DWORD,head:DWORD lea edi,brMap3D mov eax,0B4B4B4B4h mov ecx,256 rep stosd mov brMap3D[33],0 mov brStack3D,33 mov top,1 br_dfs: mov eax,top test eax,eax jz br_rooms dec eax mov ebx,brStack3D[eax*4] mov current,ebx mov count,0 xor esi,esi br_neighbors: mov edx,ebx and edx,31 cmp esi,0 jne @F cmp ebx,65 jb br_neighbor_next @@: cmp esi,1 jne @F cmp edx,29 jae br_neighbor_next @@: cmp esi,2 jne @F cmp ebx,29*32 jae br_neighbor_next @@: cmp esi,3 jne @F cmp edx,3 jb br_neighbor_next @@: mov eax,ebx add eax,brSteps3D[esi*4] cmp brMap3D[eax],0 je br_neighbor_next mov ecx,count mov brCandidates3D[ecx*4],eax inc count br_neighbor_next: inc esi cmp esi,4 jb br_neighbors cmp count,0 je br_backtrack invoke RandomRange3D,count mov eax,brCandidates3D[eax*4] mov brMap3D[eax],0 mov edx,eax add edx,current shr edx,1 mov brMap3D[edx],0 mov ecx,top mov brStack3D[ecx*4],eax inc top jmp br_dfs br_backtrack: dec top jmp br_dfs br_rooms: ; Open a small landing room so the recovered camera never faces a wall. mov brMap3D[33],0 mov brMap3D[34],0 mov brMap3D[35],0 mov brMap3D[65],0 mov brMap3D[66],0 mov brMap3D[67],0 mov brMap3D[97],0 mov brMap3D[98],0 mov brMap3D[99],0 ; Every 3x3 room includes an odd lattice node: cannot be disconnected. mov esi,12 br_room: invoke RandomRange3D,13 shl eax,1 inc eax mov ebx,eax invoke RandomRange3D,13 shl eax,1 inc eax shl eax,5 add ebx,eax mov edi,3 br_room_row: mov brMap3D[ebx],0 mov brMap3D[ebx+1],0 mov brMap3D[ebx+2],0 add ebx,32 dec edi jnz br_room_row dec esi jnz br_room ; Open connecting walls only; never carve outside the sealed border. mov esi,55 br_loop: invoke RandomRange3D,29 inc eax mov ebx,eax invoke RandomRange3D,29 inc eax shl eax,5 add ebx,eax cmp brMap3D[ebx-1],0 jne br_loop_vertical cmp brMap3D[ebx+1],0 je br_loop_open br_loop_vertical: cmp brMap3D[ebx-32],0 jne br_loop_next cmp brMap3D[ebx+32],0 jne br_loop_next br_loop_open: mov brMap3D[ebx],0 br_loop_next: dec esi jnz br_loop lea edi,brDistance3D mov eax,-1 mov ecx,1024 rep stosd mov brDistance3D[33*4],0 mov brStack3D,33 mov head,0 mov tail,1 mov brExitCell3D,33 br_bfs: mov eax,head cmp eax,tail jae br_place_games mov ebx,brStack3D[eax*4] inc head mov eax,brDistance3D[ebx*4] mov ecx,brExitCell3D cmp eax,brDistance3D[ecx*4] jbe @F mov brExitCell3D,ebx @@: xor esi,esi br_bfs_neighbor: mov eax,brSteps3D[esi*4] sar eax,1 add eax,ebx cmp brMap3D[eax],0 jne br_bfs_next cmp brDistance3D[eax*4],-1 jne br_bfs_next mov edx,brDistance3D[ebx*4] inc edx mov brDistance3D[eax*4],edx mov ecx,tail mov brStack3D[ecx*4],eax inc tail br_bfs_next: inc esi cmp esi,4 jb br_bfs_neighbor jmp br_bfs br_place_games: ; Sample distinct reachable cells at evenly spaced BFS distances. xor esi,esi br_place_game: mov eax,tail imul eax,esi xor edx,edx mov ecx,7 div ecx add eax,8 mov ebx,brStack3D[eax*4] cmp ebx,brExitCell3D jne @F mov ebx,brStack3D[eax*4+4] @@: mov brGameCells3D[esi*4],ebx inc esi cmp esi,6 jb br_place_game ret GenerateBackrooms3D ENDP BackroomsEntry3D PROC cmp brActive3D,0 jne br_entry_reset cmp engineMode,MODE_WALK jne br_entry_reset cmp hallLevel3D,0 jne br_entry_reset cmp paused3D,0 jne br_entry_reset cmp playerX,16*FP_1 jb br_entry_reset cmp playerX,17*FP_1 jae br_entry_reset cmp playerY,30*FP_1-15000 jb br_entry_reset cmp playerY,30*FP_1 jae br_entry_reset cmp playerAngle,104 jb br_entry_reset cmp playerAngle,152 ja br_entry_reset cmp keys3D[53h],0 jne br_entry_reset cmp keys3D[28h],0 jne br_entry_reset cmp keys3D[41h],0 jne br_entry_reset cmp keys3D[44h],0 jne br_entry_reset cmp keys3D[57h],0 jne br_entry_hold cmp keys3D[26h],0 je br_entry_reset br_entry_hold: mov eax,playerAngle cmp brEntryHold3D,0 je @F cmp eax,brEntryAngle3D jne br_entry_reset @@: mov brEntryAngle3D,eax mov eax,deltaTime3D add brEntryHold3D,eax cmp brEntryHold3D,2000 jb br_entry_done call BeginBackrooms3D ret br_entry_reset: mov brEntryHold3D,0 br_entry_done: ret BackroomsEntry3D ENDP BeginBackrooms3D PROC call LoadBackroomsAssets3D test eax,eax jz br_begin_done call GenerateBackrooms3D mov brActive3D,1 mov brEntryHold3D,0 mov brCutscene3D,1 mov brClock3D,0 mov brDialogue3D,0 mov paused3D,0 ; First 900ms still show the casino while camera clips through the wall. mov viewEye3D,HALL_STANDING_EYE mov viewCeiling3D,FP_1*5/2 mov interactTargetId,0 call ClearKeys3D br_begin_done: ret BeginBackrooms3D ENDP LeaveBackrooms3D PROC reward:DWORD cmp brActive3D,0 je br_leave_done cmp reward,0 je @F cmp brOwned3D,1 je @F mov brOwned3D,1 mov brEnabled3D,1 @@: invoke CopyString3D,OFFSET brAward3D,OFFSET flashMessage mov flashTimer,200 @@: mov brActive3D,0 mov brCutscene3D,0 mov brEntryHold3D,0 mov worldMap3D,OFFSET casinoMap mov hallLevel3D,0 mov playerX,16*FP_1+FP_HALF mov playerY,27*FP_1+FP_HALF mov playerAngle,384 mov viewEye3D,HALL_STANDING_EYE mov viewCeiling3D,FP_1*5/2 mov floorTexture3D,100 mov engineMode,MODE_WALK mov paused3D,0 call ClearKeys3D call SaveProgress3D br_leave_done: ret LeaveBackrooms3D ENDP HandleBackrooms3D PROC uses ebx esi edi mov eax,deltaTime3D add brClock3D,eax cmp brCutscene3D,0 je br_walk cmp brClock3D,900 jae br_fall_world mov eax,deltaTime3D imul eax,30 add playerY,eax ret br_fall_world: cmp hallLevel3D,HALL_BACKROOMS je @F mov hallLevel3D,HALL_BACKROOMS mov worldMap3D,OFFSET brMap3D mov playerX,FP_1+FP_HALF mov playerY,FP_1+FP_HALF mov playerAngle,64 mov floorTexture3D,BR_FLOOR @@: cmp brClock3D,6500 jae br_stand ; Camera fall, impact, then low-to-standing recovery; no video player. mov eax,brClock3D cmp eax,2200 jae br_impact imul eax,36 mov edx,FP_1*3/2 sub edx,eax cmp edx,FP_1/8 jge @F mov edx,FP_1/8 @@: mov viewEye3D,edx mov eax,brClock3D shr eax,5 and eax,511 mov playerAngle,eax ret br_impact: cmp eax,3100 jae br_rise mov viewEye3D,FP_1/8 mov playerAngle,64 ret br_rise: sub eax,3100 imul eax,HALL_STANDING_EYE-FP_1/8 xor edx,edx mov ecx,3400 div ecx add eax,FP_1/8 mov viewEye3D,eax ret br_stand: mov brCutscene3D,0 mov viewEye3D,HALL_STANDING_EYE call ClearKeys3D br_walk: mov eax,deltaTime3D add brDialogue3D,eax call HandlePlayerInput mov interactTargetId,0 mov interactPromptPtr,0 mov brTarget3D,-1 xor esi,esi br_target_scan: cmp esi,6 jb @F mov ebx,brExitCell3D jmp br_target_cell @@: mov ebx,brGameCells3D[esi*4] br_target_cell: mov eax,ebx and eax,31 shl eax,16 add eax,FP_HALF sub eax,playerX sar eax,8 imul eax,eax mov edi,eax mov eax,ebx shr eax,5 shl eax,16 add eax,FP_HALF sub eax,playerY sar eax,8 imul eax,eax add eax,edi cmp eax,FP_1*3/4 ja br_target_next mov brTarget3D,esi cmp esi,6 je @F mov eax,brGamePrompts3D[esi*4] mov interactPromptPtr,eax jmp br_targets_done @@: mov interactPromptPtr,OFFSET brExitPrompt3D jmp br_targets_done br_target_next: inc esi cmp esi,7 jb br_target_scan br_targets_done: invoke Pressed3D,56h test eax,eax jz @F xor brVhs3D,1 @@: invoke Pressed3D,45h test eax,eax jz br_handle_done mov esi,brTarget3D cmp esi,6 ja br_handle_done jne br_launch invoke LeaveBackrooms3D,1 ret br_launch: ; Reuse normal station dispatch; suppress all hall-specific interactions. mov eax,brGames3D[esi*4] mov interactTargetId,eax call Trigger3DInteraction call ClearKeys3D br_handle_done: ret HandleBackrooms3D ENDP RenderBackroomsDialogue3D PROC uses ebx esi edi local x:DWORD,y:DWORD,age:DWORD,offsetY:DWORD cmp brDialogue3D,9500 jae br_dialogue_done invoke DrawBoxBorder,4,179,312,57,00191711h,009C9464h,1 mov x,12 mov y,189 xor esi,esi br_letter: movzx ebx,brText3D[esi] test ebx,ebx jz br_dialogue_done ; Wrap whole words, not arbitrary characters. cmp ebx,32 jne br_letter_position mov edi,esi xor ecx,ecx br_word_length: inc edi mov al,brText3D[edi] test al,al jz br_word_end cmp al,32 je br_word_end inc ecx jmp br_word_length br_word_end: inc ecx shl ecx,3 add ecx,x cmp ecx,300 jbe br_letter_position mov x,12 add y,14 jmp br_letter_next br_letter_position: mov eax,esi imul eax,35 mov ecx,brDialogue3D sub ecx,eax js br_letter_advance cmp ecx,6400 jae br_letter_advance mov age,ecx mov offsetY,0 cmp ecx,420 jae br_letter_out mov eax,420 sub eax,ecx imul eax,18 xor edx,edx mov ecx,420 div ecx mov offsetY,eax jmp br_letter_draw br_letter_out: cmp ecx,5900 jb br_letter_draw sub ecx,5900 imul ecx,18 mov eax,ecx xor edx,edx mov ecx,500 div ecx neg eax mov offsetY,eax br_letter_draw: mov eax,age shr eax,3 mov ecx,esi shl ecx,4 add eax,ecx and eax,511 mov eax,tableSin[eax*4] sar eax,15 add eax,y add eax,offsetY mov brGlyph3D,bl invoke DrawString8x8,x,eax,OFFSET brGlyph3D,00EBE4B5h br_letter_advance: add x,8 br_letter_next: inc esi jmp br_letter br_dialogue_done: ret RenderBackroomsDialogue3D ENDP RenderBackrooms3D PROC uses ebx esi edi local exitX:DWORD,exitY:DWORD call UpdateCamera3D call RenderCeilingAndFloor call RenderWalls call PrepareCityDepth3D cmp hallLevel3D,HALL_BACKROOMS je @F call RenderSprites call RenderHall3D jmp br_camera_hud @@: xor esi,esi br_render_station: mov ebx,brGameCells3D[esi*4] mov eax,ebx and eax,31 shl eax,16 add eax,FP_HALF mov brProp3D.posX,eax mov eax,ebx shr eax,5 shl eax,16 add eax,FP_HALF mov brProp3D.posY,eax mov eax,brGamePacks3D[esi*4] mov brProp3D.asset,eax mov eax,brGameFrames3D[esi*4] mov brProp3D.frame,eax invoke DrawCityObject3D,OFFSET brProp3D,0 inc esi cmp esi,6 jb br_render_station ; Upright door on a neighboring solid wall; collision map stays unchanged. mov ebx,brExitCell3D mov eax,ebx and eax,31 shl eax,16 mov exitX,eax mov eax,ebx shr eax,5 shl eax,16 mov exitY,eax cmp brMap3D[ebx-32],0 je br_exit_south add exitY,512 jmp br_exit_y_door br_exit_south: cmp brMap3D[ebx+32],0 je br_exit_west add exitY,FP_1-512 br_exit_y_door: mov eax,exitX add eax,FP_1 invoke DrawCityVertical3D,1,exitY,exitX,eax,0,FP_1*21/10,BR_EXIT jmp br_exit_drawn br_exit_west: cmp brMap3D[ebx-1],0 je br_exit_east add exitX,512 jmp br_exit_x_door br_exit_east: add exitX,FP_1-512 br_exit_x_door: mov eax,exitY add eax,FP_1 invoke DrawCityVertical3D,0,exitX,exitY,eax,0,FP_1*21/10,BR_EXIT br_exit_drawn: cmp brVhs3D,0 je br_camera_hud ; Deterministic screen noise, independent of gameplay RNG. lea edi,screenBuffer mov ecx,SCREEN_SIZE mov ebx,brClock3D br_vhs_pixel: imul ebx,1664525 add ebx,1013904223 mov eax,[edi] ; Reserve two low bits per channel: adding 0..3 cannot carry into RGB. and eax,00FCFCFCh mov edx,ebx shr edx,30 imul edx,00010101h add eax,edx stosd dec ecx jnz br_vhs_pixel mov esi,2 br_scanline: imul eax,esi,SCREEN_W*4 lea edi,screenBuffer[eax] mov ecx,SCREEN_W br_scan_pixel: mov eax,[edi] and eax,00FCFCFCh mov edx,eax shr edx,2 sub eax,edx stosd loop br_scan_pixel add esi,6 cmp esi,SCREEN_H jb br_scanline br_camera_hud: mov eax,brClock3D xor edx,edx mov ecx,1000 div ecx xor esi,esi mov esi,6 br_time_pair: xor edx,edx mov ecx,60 div ecx push eax mov eax,edx xor edx,edx mov ecx,10 div ecx add al,'0' add dl,'0' mov brTime3D[esi],al mov brTime3D[esi+1],dl pop eax sub esi,3 jns br_time_pair invoke DrawString8x8,224,12,OFFSET brTime3D,00EEEEDDh invoke DrawString8x8,25,12,OFFSET brRec3D,00EEEEDDh test brClock3D,512 jnz @F invoke DrawBox,12,13,7,7,00EE3030h @@: invoke DrawString8x8,8,29,OFFSET brHelp3D,00C8C8A0h cmp brCutscene3D,0 je br_hud_walk cmp brClock3D,2200 jb br_render_done cmp brClock3D,2800 jae br_render_done invoke DrawBox,0,0,SCREEN_W,SCREEN_H,00080704h ret br_hud_walk: cmp interactPromptPtr,0 je @F invoke DrawString8x8,112,158,interactPromptPtr,00F1F1B5h @@: call RenderBackroomsDialogue3D br_render_done: ret RenderBackrooms3D ENDP ; -1 = disabled; 0 = unlucky; 1 = lucky. Caller latches once per round. BackroomsLuck3D PROC cmp brOwned3D,1 jne br_luck_off cmp brEnabled3D,1 jne br_luck_off cmp brActive3D,0 jne br_luck_off cmp tournamentMode,0 jne br_luck_off cmp obsActive3D,0 jne br_luck_off invoke RandomRange3D,100 cmp eax,90 setb al movzx eax,al ret br_luck_off: mov eax,-1 ret BackroomsLuck3D ENDP ; Select a physically possible roulette result by actual net return. BackroomsWheelLuck3D PROC uses ebx esi edi original:DWORD local desired:DWORD,total:DWORD,count:DWORD call BackroomsLuck3D cmp eax,-1 je br_wheel_original mov desired,eax mov count,0 xor edi,edi br_wheel_result: mov total,0 xor esi,esi br_wheel_bet: invoke WheelBetMultiplier3D,esi,edi imul eax,wheelBets3D[esi*4] add total,eax inc esi cmp esi,49 jb br_wheel_bet mov eax,total cmp eax,wheelStake3D seta al movzx eax,al cmp eax,desired jne br_wheel_next inc count invoke RandomRange3D,count test eax,eax jnz br_wheel_next mov original,edi br_wheel_next: inc edi cmp edi,37 jb br_wheel_result br_wheel_original: mov eax,original ret BackroomsWheelLuck3D ENDP ; Permute a real deck by swapping cards, preserving all 52 unique identities. BackroomsDeck3D PROC uses ebx esi edi deck:DWORD,targets:DWORD,count:DWORD mov edi,deck mov esi,targets xor ebx,ebx br_deck_position: cmp ebx,count jae br_deck_done mov eax,[esi+ebx*4] cmp eax,52 jae br_deck_next xor ecx,ecx br_deck_find: cmp ecx,52 jae br_deck_next cmp [edi+ecx*4],eax je br_deck_swap inc ecx jmp br_deck_find br_deck_swap: mov edx,[edi+ebx*4] mov [edi+ecx*4],edx mov [edi+ebx*4],eax br_deck_next: inc ebx jmp br_deck_position br_deck_done: ret BackroomsDeck3D ENDP BackroomsBlackjackDeck3D PROC uses ebx esi edi call BackroomsLuck3D cmp eax,-1 je br_bj_done mov ebx,eax lea edi,brDeckTargets3D mov eax,-1 mov ecx,16 rep stosd ; Two aces + picture cards remain distinct. Party seats keep their cards. mov ecx,cbBotCount3D add ecx,2 cmp ebx,1 jne br_bj_unlucky mov brDeckTargets3D,12 mov brDeckTargets3D[ecx*4],11 dec ecx mov brDeckTargets3D[ecx*4],8 inc ecx add ecx,ecx dec ecx mov brDeckTargets3D[ecx*4],7 jmp br_bj_apply br_bj_unlucky: mov brDeckTargets3D,8 mov brDeckTargets3D[ecx*4],7 dec ecx mov brDeckTargets3D[ecx*4],12 inc ecx add ecx,ecx dec ecx mov brDeckTargets3D[ecx*4],11 br_bj_apply: invoke BackroomsDeck3D,OFFSET cbDeck3D,OFFSET brDeckTargets3D,10 br_bj_done: ret BackroomsBlackjackDeck3D ENDP BackroomsPokerDeck3D PROC uses ebx edi call BackroomsLuck3D cmp eax,-1 je br_pk_done mov ebx,eax lea edi,brDeckTargets3D mov eax,-1 mov ecx,16 rep stosd ; Fixed board creates a real royal flush for the lucky seat, no duplicate cards. ; Flop deck 5,6,7; turn 9; river 11. Burns remain shuffled. mov brDeckTargets3D[5*4],8 mov brDeckTargets3D[6*4],9 mov brDeckTargets3D[7*4],10 mov brDeckTargets3D[9*4],13 mov brDeckTargets3D[11*4],27 mov ecx,pkButton3D xor ecx,1 xor ebx,1 xor ecx,ebx mov brDeckTargets3D[ecx*4],11 mov brDeckTargets3D[ecx*4+8],12 xor ecx,1 mov brDeckTargets3D[ecx*4],16 mov brDeckTargets3D[ecx*4+8],30 invoke BackroomsDeck3D,OFFSET pkDeck3D,OFFSET brDeckTargets3D,12 br_pk_done: ret BackroomsPokerDeck3D ENDP BackroomsDurakDeck3D PROC uses ebx esi edi call BackroomsLuck3D cmp eax,-1 je br_dk_done mov ebx,eax ; Favor six initial trump cards, preserving the compacted 36-card deck. ; A poor move can still lose: no settlement or rule is overridden. mov ecx,0 br_dk_pair: mov eax,ecx add eax,7 cmp ebx,1 jne @F add eax,26 @@: mov edx,ecx shl edx,1 xor esi,esi br_dk_find: cmp esi,36 jae br_dk_next cmp dkDeck3D[esi*4],eax je br_dk_swap inc esi jmp br_dk_find br_dk_swap: mov edi,dkDeck3D[edx*4] mov dkDeck3D[esi*4],edi mov dkDeck3D[edx*4],eax br_dk_next: inc ecx cmp ecx,6 jb br_dk_pair ; Exposed trump must match the favored side, without introducing duplicates. mov eax,43 cmp ebx,1 jne @F mov eax,30 @@: xor esi,esi br_dk_trump_find: cmp dkDeck3D[esi*4],eax je br_dk_trump_swap inc esi cmp esi,36 jb br_dk_trump_find jmp br_dk_done br_dk_trump_swap: mov edx,dkDeck3D[35*4] mov dkDeck3D[esi*4],edx mov dkDeck3D[35*4],eax br_dk_done: ret BackroomsDurakDeck3D ENDP ; Reorder only at loading time, before shell knowledge or previews exist. ; This biases real cartridges, never changes a cartridge after it is revealed. BackroomsBuckshotLuck3D PROC uses ebx esi edi call BackroomsLuck3D cmp eax,-1 je br_bs_done mov brBuckshotLuck3D,eax xor eax,bs3d_turn mov ebx,eax xor esi,esi br_bs_shell: ; Only permute cartridges already loaded; preserve advertised counts. xor eax,eax cmp ebx,1 jne br_bs_blanks_first cmp esi,bs3d_liveCount setb al jmp br_bs_store br_bs_blanks_first: cmp esi,bs3d_blankCount setae al br_bs_store: mov bs3d_shells[esi*4],eax inc esi cmp esi,bs3d_shellCount jb br_bs_shell br_bs_done: ret BackroomsBuckshotLuck3D ENDP BackroomsRussianLuck3D PROC ; Cylinder is arranged before LOAD/SPIN; shot animation consumes it unchanged. call BackroomsLuck3D cmp eax,-1 je br_rr_done mov brRussianLuck3D,eax mov rr3d_turn,eax call BackroomsRussianCylinder3D br_rr_done: ret BackroomsRussianLuck3D ENDP ; Search legal cylinders before loading animation, not at the trigger frame. ; Keep selected bullet count. Lucky cylinders eliminate guests, never player; ; subsequent reloads retain the single round's luck roll. BackroomsRussianCylinder3D PROC uses ebx esi edi local candidate:DWORD,alive:DWORD,actor:DWORD,step:DWORD cmp brRussianLuck3D,-1 je br_cylinder_done cmp brRussianLuck3D,0 jne br_cylinder_search mov eax,1 mov ecx,rr3d_bullets shl eax,cl dec eax mov rr3d_mask,eax mov rr3d_turn,0 mov rr3d_chamber,0 ret br_cylinder_search: mov candidate,1 br_cylinder_candidate: mov eax,candidate xor ecx,ecx br_cylinder_popcount: shr eax,1 adc ecx,0 test eax,eax jnz br_cylinder_popcount cmp ecx,rr3d_bullets jne br_cylinder_next mov eax,rrPartyAlive3D mov alive,eax mov eax,rr3d_turn mov actor,eax mov step,0 br_cylinder_simulate: mov eax,candidate mov ecx,step bt eax,ecx jnc br_cylinder_advance mov ecx,actor test ecx,ecx jz br_cylinder_next btr alive,ecx cmp alive,1 je br_cylinder_found br_cylinder_advance: inc actor mov eax,actor cmp eax,rrPartySize3D jb @F mov actor,0 xor eax,eax @@: bt alive,eax jnc br_cylinder_advance inc step cmp step,6 jb br_cylinder_simulate br_cylinder_found: mov eax,candidate mov rr3d_mask,eax mov rr3d_chamber,0 ret br_cylinder_next: inc candidate cmp candidate,64 jb br_cylinder_candidate br_cylinder_done: ret BackroomsRussianCylinder3D ENDP HandleBackroomsInventory3D PROC cmp brOwned3D,0 jne @F mov brInventoryOpen3D,0 xor eax,eax ret @@: invoke Pressed3D,52h test eax,eax jz @F xor brInventoryOpen3D,1 mov eax,1 ret @@: cmp brInventoryOpen3D,0 je br_inventory_unhandled invoke Pressed3D,09h test eax,eax jz @F mov brInventoryOpen3D,0 @@: invoke Pressed3D,45h test eax,eax jz @F xor brEnabled3D,1 call SaveProgress3D @@: mov eax,1 ret br_inventory_unhandled: xor eax,eax ret HandleBackroomsInventory3D ENDP RenderBackroomsInventory3D PROC uses esi invoke DrawBox,0,0,320,240,0015191Bh invoke DrawBoxBorder,8,8,304,224,001D2425h,00D8BC6Ah,1 invoke DrawString8x8,24,24,OFFSET brInventory3D,00EED5A0h invoke DrawString8x8,24,52,OFFSET brInventoryRules1,00FFFFFFh invoke DrawString8x8,24,72,OFFSET brInventoryRules2,00FFFFFFh invoke DrawString8x8,24,100,OFFSET brInventoryRules3,00DDCDAAh invoke DrawString8x8,24,120,OFFSET brInventoryRules4,00DDCDAAh invoke DrawString8x8,24,140,OFFSET brInventoryRules5,00DDCDAAh invoke DrawString8x8,24,160,OFFSET brInventoryRules6,00DDCDAAh invoke DrawString8x8,24,188,OFFSET brInventoryHelp3D,00D8BC6Ah mov esi,OFFSET brDisabledText3D cmp brEnabled3D,0 je @F mov esi,OFFSET brEnabledText3D @@: invoke DrawString8x8,264,188,esi,00FFFFFFh invoke DrawString8x8,24,212,OFFSET brInventoryReturn3D,0099AAA5h ret RenderBackroomsInventory3D ENDP