.data rrPartyShotReady db "build\actions\rr-party-ready.bmp",0 rrPartyShotTurn db "build\actions\rr-party-turn.bmp",0 rrPartyShotOut db "build\actions\rr-party-out.bmp",0 rrPartyShotWin db "build\actions\rr-party-win.bmp",0 rrPartyShotExit db "build\actions\rr-party-exit.bmp",0 .code RunRRPartyTest3D PROC uses ebx esi edi local rounds:DWORD,ticks:DWORD,bank:DWORD,savedSeed:DWORD,savedMask:DWORD,savedAlive:DWORD,phase:DWORD mov engineMode,MODE_RUSSIAN call InitRussianGame3D test eax,eax jz rr_party_test_art_fail cmp rrPartyArt3D.pixels,0 je rr_party_test_art_fail mov rr3d_bet,50 mov rr3d_bullets,1 mov bankroll,10000 mov mouseClick3D,1 mov mouseX3D,230 mov mouseY3D,232 call RRPartyInput3D cmp rrPartyCount3D,3 jne rr_party_test_input_fail cmp mouseClick3D,0 jne rr_party_test_input_fail call RenderRussianGame3D invoke WriteActionSnapshot3D,OFFSET rrPartyShotReady mov rr3d_bullets,2 call StartRussianRound3D cmp rrPartyAlive3D,15 jne rr_party_test_rules_fail cmp rrPartySize3D,4 jne rr_party_test_rules_fail cmp rrPartyStake3D,50 jne rr_party_test_money_fail cmp rrPartyReloads3D,1 jne rr_party_test_rules_fail cmp bankroll,9950 jne rr_party_test_money_fail invoke RRPartySetCount3D,2 cmp rrPartyCount3D,3 jne rr_party_test_input_fail ; Elimination removes one seat and consumes one round, not the entire match. mov rr3d_turn,2 mov rr3d_chamber,0 mov rr3d_mask,5 mov rr3d_shot,1 mov rr3d_state,RR_FIRE call AdvanceRussianScene3D cmp rrPartyAlive3D,11 jne rr_party_test_rules_fail cmp rr3d_mask,4 jne rr_party_test_rules_fail cmp rr3d_state,RR_DRY jne rr_party_test_rules_fail cmp bankroll,9950 jne rr_party_test_money_fail mov rr3d_timer,350 call RenderRussianGame3D invoke WriteActionSnapshot3D,OFFSET rrPartyShotOut call AdvanceRussianScene3D cmp rr3d_turn,3 jne rr_party_test_rules_fail cmp rr3d_chamber,1 jne rr_party_test_rules_fail cmp rr3d_mask,4 jne rr_party_test_rules_fail ; The cursor wraps and skips a previously eliminated seat. mov rr3d_turn,1 mov rr3d_state,RR_DRY call AdvanceRussianScene3D cmp rr3d_turn,3 jne rr_party_test_rules_fail ; Consuming the last loaded round reloads without taking another stake. mov rr3d_mask,0 mov rr3d_state,RR_DRY call AdvanceRussianScene3D cmp rr3d_state,RR_LOAD jne rr_party_test_rules_fail cmp rr3d_turn,0 jne rr_party_test_rules_fail cmp rrPartyReloads3D,2 jne rr_party_test_rules_fail cmp bankroll,9950 jne rr_party_test_money_fail ; The final surviving player receives the locked, not subsequently edited, pool. mov rrPartyAlive3D,3 mov rr3d_turn,1 mov rr3d_chamber,2 mov rr3d_mask,4 mov rr3d_shot,1 mov rr3d_state,RR_FIRE mov rr3d_bet,999 call AdvanceRussianScene3D cmp rr3d_state,RR_WIN jne rr_party_test_rules_fail cmp rrPartyAlive3D,1 jne rr_party_test_rules_fail cmp rr3d_payout,200 jne rr_party_test_money_fail cmp bankroll,10150 jne rr_party_test_money_fail call RRPartyWin3D call AdvanceRussianScene3D cmp bankroll,10150 jne rr_party_test_money_fail mov rr3d_bet,50 call RenderRussianGame3D invoke WriteActionSnapshot3D,OFFSET rrPartyShotWin ; 600 full matches, 2/3 guests, 1..3 rounds loaded, 16/50/250 ms updates. mov edi,2 rr_party_test_size: mov rr3d_state,RR_READY invoke RRPartySetCount3D,edi mov rounds,300 rr_party_test_match: mov engineMode,MODE_RUSSIAN mov rr3d_state,RR_READY mov bankroll,10000 mov rr3d_bet,50 mov eax,rounds imul eax,5231 add eax,edi mov rngSeed3D,eax mov eax,rounds xor edx,edx mov ecx,3 div ecx inc edx mov rr3d_bullets,edx mov eax,16 cmp edx,1 je @F mov eax,50 cmp edx,2 je @F mov eax,250 @@: mov deltaTime3D,eax call StartRussianRound3D mov ticks,0 rr_party_test_tick: cmp rrPartySettled3D,0 jne rr_party_test_ending mov eax,rrPartyAlive3D test eax,1 jz rr_party_test_rules_fail mov eax,rr3d_mask cmp eax,63 ja rr_party_test_rules_fail mov eax,rr3d_turn cmp eax,rrPartySize3D jae rr_party_test_rules_fail cmp rr3d_state,RR_DRY je @F ; the outgoing seat may already be eliminated during its fade bt rrPartyAlive3D,eax jnc rr_party_test_rules_fail @@: cmp bankroll,9950 jne rr_party_test_money_fail cmp rr3d_state,RR_PLAYER jne rr_party_test_ending mov pressedKeys3D[20h],1 rr_party_test_ending: call HandleRussianInput3D call ClearKeys3D inc ticks cmp ticks,20000 jae rr_party_test_stuck_fail cmp rr3d_state,RR_WIN je rr_party_test_won cmp engineMode,MODE_WALK jne rr_party_test_tick cmp bankroll,9950 jne rr_party_test_money_fail cmp rrPartySettled3D,1 jne rr_party_test_money_fail jmp rr_party_test_next rr_party_test_won: mov eax,edi inc eax imul eax,50 cmp rr3d_payout,eax jne rr_party_test_money_fail add eax,9950 cmp bankroll,eax jne rr_party_test_money_fail mov bank,eax call RRPartyWin3D mov eax,bank cmp bankroll,eax jne rr_party_test_money_fail rr_party_test_next: dec rounds jnz rr_party_test_match inc edi cmp edi,4 jb rr_party_test_size ; Native rendering is pure; the active guest and empty seats must be readable. mov rr3d_state,RR_READY mov bankroll,10000 mov engineMode,MODE_RUSSIAN call StartRussianRound3D mov rr3d_state,RR_RAISE mov rr3d_turn,2 mov rr3d_timer,400 mov eax,rngSeed3D mov savedSeed,eax mov eax,rr3d_mask mov savedMask,eax mov eax,rrPartyAlive3D mov savedAlive,eax mov ebx,8 rr_party_test_repeat_render: call RenderRussianGame3D dec ebx jnz rr_party_test_repeat_render mov eax,savedSeed cmp rngSeed3D,eax jne rr_party_test_render_fail mov eax,savedMask cmp rr3d_mask,eax jne rr_party_test_render_fail mov eax,savedAlive cmp rrPartyAlive3D,eax jne rr_party_test_render_fail cmp rr3d_timer,400 jne rr_party_test_render_fail cmp bankroll,9950 jne rr_party_test_money_fail invoke WriteActionSnapshot3D,OFFSET rrPartyShotTurn ; Escape modal freezes every animation phase, not just the player's input. mov phase,RR_LOAD rr_party_test_exit_phase: mov rr3d_state,RR_READY mov bankroll,10000 mov engineMode,MODE_RUSSIAN call StartRussianRound3D mov eax,phase mov rr3d_state,eax mov rr3d_timer,37 mov eax,rngSeed3D mov savedSeed,eax mov eax,rr3d_mask mov savedMask,eax call CardTableEscape3D cmp cardExitActive3D,1 jne rr_party_test_input_fail call HandleRussianInput3D cmp rr3d_timer,37 jne rr_party_test_input_fail mov eax,savedSeed cmp rngSeed3D,eax jne rr_party_test_input_fail mov eax,savedMask cmp rr3d_mask,eax jne rr_party_test_input_fail mov pressedKeys3D[4Eh],1 call HandleRussianInput3D cmp cardExitActive3D,0 jne rr_party_test_input_fail cmp rr3d_timer,37 jne rr_party_test_input_fail call RequestCardExit3D cmp phase,RR_RAISE jne @F call RenderRussianGame3D invoke WriteActionSnapshot3D,OFFSET rrPartyShotExit @@: mov pressedKeys3D[59h],1 call HandleRussianInput3D cmp engineMode,MODE_WALK jne rr_party_test_input_fail cmp bankroll,9950 jne rr_party_test_money_fail call AbortRussianRound3D cmp bankroll,9950 jne rr_party_test_money_fail inc phase cmp phase,RR_WIN jb rr_party_test_exit_phase ; Zero bank and invalid bullet counts cannot create a paid or stuck match. mov engineMode,MODE_RUSSIAN mov rr3d_state,RR_READY mov bankroll,0 call StartRussianRound3D cmp rr3d_state,RR_READY jne rr_party_test_money_fail mov bankroll,10000 mov rr3d_bullets,0 call StartRussianRound3D cmp rr3d_state,RR_READY jne rr_party_test_money_fail cmp bankroll,10000 jne rr_party_test_money_fail mov rr3d_bullets,1 invoke RRPartySetCount3D,1 mov cardExitActive3D,0 call ClearKeys3D xor eax,eax ret rr_party_test_art_fail: mov eax,8201 ret rr_party_test_input_fail: mov eax,8202 ret rr_party_test_rules_fail: mov eax,8203 ret rr_party_test_money_fail: mov eax,8204 ret rr_party_test_stuck_fail: mov eax,8205 ret rr_party_test_render_fail: mov eax,8206 ret RunRRPartyTest3D ENDP